diff options
677 files changed, 24524 insertions, 11037 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 4860bebd32..77346a4929 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,7 +1,7 @@ env: CIRRUS_CLONE_DEPTH: 1 -freebsd_12_task: +freebsd_task: env: GIT_PROVE_OPTS: "--timer --jobs 10" GIT_TEST_OPTS: "--no-chain-lint --no-bin-wrappers" @@ -9,7 +9,7 @@ freebsd_12_task: DEFAULT_TEST_TARGET: prove DEVELOPER: 1 freebsd_instance: - image_family: freebsd-12-3 + image_family: freebsd-13-2 memory: 2G install_script: pkg install -y gettext gmake perl5 @@ -19,4 +19,4 @@ freebsd_12_task: build_script: - su git -c gmake test_script: - - su git -c 'gmake test' + - su git -c 'gmake DEFAULT_UNIT_TEST_TARGET=unit-tests-prove test unit-tests' diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 952c7c3a2a..37654cdfd7 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,4 +4,7 @@ a mailing list (git@vger.kernel.org) for code submissions, code reviews, and bug reports. Nevertheless, you can use GitGitGadget (https://gitgitgadget.github.io/) to conveniently send your Pull Requests commits to our mailing list. +For a single-commit pull request, please *leave the pull request description +empty*: your commit message itself should describe your changes. + Please read the "guidelines for contributing" linked above! diff --git a/.github/workflows/check-whitespace.yml b/.github/workflows/check-whitespace.yml index a58e2dc8ad..a241a63428 100644 --- a/.github/workflows/check-whitespace.yml +++ b/.github/workflows/check-whitespace.yml @@ -19,7 +19,7 @@ jobs: check-whitespace: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index e5532d381b..53cf12fe04 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -38,7 +38,7 @@ jobs: COVERITY_LANGUAGE: cxx COVERITY_PLATFORM: overridden-below steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: install minimal Git for Windows SDK if: contains(matrix.os, 'windows') uses: git-for-windows/setup-git-for-windows-sdk@v1 @@ -98,7 +98,7 @@ jobs: # A cache miss will add ~30s to create, but a cache hit will save minutes. - name: restore the Coverity Build Tool id: cache - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: ${{ runner.temp }}/cov-analysis key: cov-build-${{ env.COVERITY_LANGUAGE }}-${{ env.COVERITY_PLATFORM }}-${{ steps.lookup.outputs.hash }} @@ -141,7 +141,7 @@ jobs: esac - name: cache the Coverity Build Tool if: steps.cache.outputs.cache-hit != 'true' - uses: actions/cache/save@v3 + uses: actions/cache/save@v4 with: path: ${{ runner.temp }}/cov-analysis key: cov-build-${{ env.COVERITY_LANGUAGE }}-${{ env.COVERITY_PLATFORM }}-${{ steps.lookup.outputs.hash }} diff --git a/.github/workflows/l10n.yml b/.github/workflows/l10n.yml index 6c3849658a..e2c3dbdcb5 100644 --- a/.github/workflows/l10n.yml +++ b/.github/workflows/l10n.yml @@ -63,9 +63,10 @@ jobs: origin \ ${{ github.ref }} \ $args - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v5 with: go-version: '>=1.16' + cache: false - name: Install git-po-helper run: go install github.com/git-l10n/git-po-helper@main - name: Install other dependencies @@ -91,14 +92,13 @@ jobs: cat git-po-helper.out exit $exit_code - name: Create comment in pull request for report - uses: mshick/add-pr-comment@v1 + uses: mshick/add-pr-comment@v2 if: >- always() && github.event_name == 'pull_request_target' && env.COMMENT_BODY != '' with: repo-token: ${{ secrets.GITHUB_TOKEN }} - repo-token-user-login: 'github-actions[bot]' message: > ${{ steps.check-commits.outcome == 'failure' && 'Errors and warnings' || 'Warnings' }} found by [git-po-helper](https://github.com/git-l10n/git-po-helper#readme) in workflow diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9fdbd54028..683a2d633e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -63,7 +63,7 @@ jobs: echo "skip_concurrent=$skip_concurrent" >>$GITHUB_OUTPUT - name: skip if the commit or tree was already tested id: skip-if-redundant - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: steps.check-ref.outputs.enabled == 'yes' with: github-token: ${{secrets.GITHUB_TOKEN}} @@ -112,7 +112,7 @@ jobs: group: windows-build-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: git-for-windows/setup-git-for-windows-sdk@v1 - name: build shell: bash @@ -123,7 +123,7 @@ jobs: - name: zip up tracked files run: git archive -o artifacts/tracked.tar.gz HEAD - name: upload tracked files and build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: windows-artifacts path: artifacts @@ -140,7 +140,7 @@ jobs: cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - name: download tracked files and build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: windows-artifacts path: ${{github.workspace}} @@ -157,7 +157,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: failed-tests-windows path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -173,10 +173,10 @@ jobs: group: vs-build-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: git-for-windows/setup-git-for-windows-sdk@v1 - name: initialize vcpkg - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: 'microsoft/vcpkg' path: 'compat/vcbuild/vcpkg' @@ -212,7 +212,7 @@ jobs: - name: zip up tracked files run: git archive -o artifacts/tracked.tar.gz HEAD - name: upload tracked files and build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: vs-artifacts path: artifacts @@ -230,7 +230,7 @@ jobs: steps: - uses: git-for-windows/setup-git-for-windows-sdk@v1 - name: download tracked files and build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: vs-artifacts path: ${{github.workspace}} @@ -248,7 +248,7 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: failed-tests-windows path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -266,6 +266,9 @@ jobs: - jobname: linux-sha256 cc: clang pool: ubuntu-latest + - jobname: linux-reftable + cc: clang + pool: ubuntu-latest - jobname: linux-gcc cc: gcc cc_package: gcc-8 @@ -277,6 +280,9 @@ jobs: - jobname: osx-clang cc: clang pool: macos-13 + - jobname: osx-reftable + cc: clang + pool: macos-13 - jobname: osx-gcc cc: gcc cc_package: gcc-13 @@ -287,6 +293,9 @@ jobs: - jobname: linux-leaks cc: gcc pool: ubuntu-latest + - jobname: linux-reftable-leaks + cc: gcc + pool: ubuntu-latest - jobname: linux-asan-ubsan cc: clang pool: ubuntu-latest @@ -297,7 +306,7 @@ jobs: runs_on_pool: ${{matrix.vector.pool}} runs-on: ${{matrix.vector.pool}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: ci/install-dependencies.sh - run: ci/run-build-and-tests.sh - name: print test failures @@ -305,10 +314,21 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: failed-tests-${{matrix.vector.jobname}} path: ${{env.FAILED_TEST_ARTIFACTS}} + fuzz-smoke-test: + name: fuzz smoke test + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + env: + CC: clang + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: ci/install-dependencies.sh + - run: ci/run-build-and-minimal-fuzzers.sh dockerized: name: ${{matrix.vector.jobname}} (${{matrix.vector.image}}) needs: ci-config @@ -331,9 +351,9 @@ jobs: runs-on: ubuntu-latest container: ${{matrix.vector.image}} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 if: matrix.vector.jobname != 'linux32' - - uses: actions/checkout@v1 + - uses: actions/checkout@v1 # cannot be upgraded because Node.js Actions aren't supported in this container if: matrix.vector.jobname == 'linux32' - run: ci/install-docker-dependencies.sh - run: ci/run-build-and-tests.sh @@ -342,13 +362,13 @@ jobs: run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' && matrix.vector.jobname != 'linux32' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: failed-tests-${{matrix.vector.jobname}} path: ${{env.FAILED_TEST_ARTIFACTS}} - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' && matrix.vector.jobname == 'linux32' - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v1 # cannot be upgraded because Node.js Actions aren't supported in this container with: name: failed-tests-${{matrix.vector.jobname}} path: ${{env.FAILED_TEST_ARTIFACTS}} @@ -362,7 +382,7 @@ jobs: group: static-analysis-${{ github.ref }} cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: ci/install-dependencies.sh - run: ci/run-static-analysis.sh - run: ci/check-directional-formatting.bash @@ -385,7 +405,7 @@ jobs: artifact: sparse-20.04 - name: Install the current `sparse` package run: sudo dpkg -i sparse-20.04/sparse_*.deb - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install other dependencies run: ci/install-dependencies.sh - run: make sparse @@ -400,6 +420,6 @@ jobs: jobname: Documentation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: ci/install-dependencies.sh - run: ci/test-documentation.sh diff --git a/.gitignore b/.gitignore index 5e56e471b3..612c0f6a0f 100644 --- a/.gitignore +++ b/.gitignore @@ -135,6 +135,7 @@ /git-remote-ext /git-repack /git-replace +/git-replay /git-request-pull /git-rerere /git-reset diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000..c0fa2fe90b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,104 @@ +default: + timeout: 2h + +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + - if: $CI_COMMIT_TAG + - if: $CI_COMMIT_REF_PROTECTED == "true" + +test:linux: + image: $image + before_script: + - ./ci/install-docker-dependencies.sh + script: + - useradd builder --create-home + - chown -R builder "${CI_PROJECT_DIR}" + - sudo --preserve-env --set-home --user=builder ./ci/run-build-and-tests.sh + after_script: + - | + if test "$CI_JOB_STATUS" != 'success' + then + sudo --preserve-env --set-home --user=builder ./ci/print-test-failures.sh + fi + parallel: + matrix: + - jobname: linux-sha256 + image: ubuntu:latest + CC: clang + - jobname: linux-reftable + image: ubuntu:latest + CC: clang + - jobname: linux-gcc + image: ubuntu:20.04 + CC: gcc + CC_PACKAGE: gcc-8 + - jobname: linux-TEST-vars + image: ubuntu:20.04 + CC: gcc + CC_PACKAGE: gcc-8 + - jobname: linux-gcc-default + image: ubuntu:latest + CC: gcc + - jobname: linux-leaks + image: ubuntu:latest + CC: gcc + - jobname: linux-reftable-leaks + image: ubuntu:latest + CC: gcc + - jobname: linux-asan-ubsan + image: ubuntu:latest + CC: clang + - jobname: pedantic + image: fedora:latest + - jobname: linux-musl + image: alpine:latest + artifacts: + paths: + - t/failed-test-artifacts + when: on_failure + +test:osx: + image: $image + tags: + - saas-macos-medium-m1 + variables: + TEST_OUTPUT_DIRECTORY: "/Volumes/RAMDisk" + before_script: + # Create a 4GB RAM disk that we use to store test output on. This small hack + # significantly speeds up tests by more than a factor of 2 because the + # macOS runners use network-attached storage as disks, which is _really_ + # slow with the many small writes that our tests do. + - sudo diskutil apfs create $(hdiutil attach -nomount ram://8192000) RAMDisk + - ./ci/install-dependencies.sh + script: + - ./ci/run-build-and-tests.sh + after_script: + - | + if test "$CI_JOB_STATUS" != 'success' + then + ./ci/print-test-failures.sh + mv "$TEST_OUTPUT_DIRECTORY"/failed-test-artifacts t/ + fi + parallel: + matrix: + - jobname: osx-clang + image: macos-13-xcode-14 + CC: clang + - jobname: osx-reftable + image: macos-13-xcode-14 + CC: clang + artifacts: + paths: + - t/failed-test-artifacts + when: on_failure + +static-analysis: + image: ubuntu:22.04 + variables: + jobname: StaticAnalysis + before_script: + - ./ci/install-docker-dependencies.sh + script: + - ./ci/run-static-analysis.sh + - ./ci/check-directional-formatting.bash diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 0215b1fd4c..e58917c50a 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -130,11 +130,11 @@ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. -Community Impact Guidelines were inspired by +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. For answers to common questions about this code of conduct, see the FAQ at -[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 8d3a467c01..32e69f798e 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -446,12 +446,41 @@ For C programs: detail. - The first #include in C files, except in platform specific compat/ - implementations and sha1dc/, must be either "git-compat-util.h" or - one of the approved headers that includes it first for you. (The - approved headers currently include "builtin.h", - "t/helper/test-tool.h", "xdiff/xinclude.h", or - "reftable/system.h"). You do not have to include more than one of - these. + implementations and sha1dc/, must be <git-compat-util.h>. This + header file insulates other header files and source files from + platform differences, like which system header files must be + included in what order, and what C preprocessor feature macros must + be defined to trigger certain features we expect out of the system. + A collorary to this is that C files should not directly include + system header files themselves. + + There are some exceptions, because certain group of files that + implement an API all have to include the same header file that + defines the API and it is convenient to include <git-compat-util.h> + there. Namely: + + - the implementation of the built-in commands in the "builtin/" + directory that include "builtin.h" for the cmd_foo() prototype + definition, + + - the test helper programs in the "t/helper/" directory that include + "t/helper/test-tool.h" for the cmd__foo() prototype definition, + + - the xdiff implementation in the "xdiff/" directory that includes + "xdiff/xinclude.h" for the xdiff machinery internals, + + - the unit test programs in "t/unit-tests/" directory that include + "t/unit-tests/test-lib.h" that gives them the unit-tests + framework, and + + - the source files that implement reftable in the "reftable/" + directory that include "reftable/system.h" for the reftable + internals, + + are allowed to assume that they do not have to include + <git-compat-util.h> themselves, as it is included as the first + '#include' in these header files. These headers must be the first + header file to be "#include"d in them, though. - A C file must directly include the header files that declare the functions and the types it uses, except for the functions and types @@ -490,7 +519,7 @@ For Perl programs: - Most of the C guidelines above apply. - - We try to support Perl 5.8 and later ("use Perl 5.008"). + - We try to support Perl 5.8.1 and later ("use Perl 5.008001"). - use strict and use warnings are strongly preferred. @@ -518,7 +547,7 @@ For Perl programs: For Python scripts: - - We follow PEP-8 (http://www.python.org/dev/peps/pep-0008/). + - We follow PEP-8 (https://peps.python.org/pep-0008/). - As a minimum, we aim to be compatible with Python 2.7. @@ -578,7 +607,7 @@ Externally Visible Names . The variable name describes the effect of tweaking this knob. The section and variable names that consist of multiple words are - formed by concatenating the words without punctuations (e.g. `-`), + formed by concatenating the words without punctuation marks (e.g. `-`), and are broken using bumpyCaps in documentation as a hint to the reader. @@ -666,6 +695,11 @@ Writing Documentation: <new-branch-name> --template=<template-directory> + When a placeholder is cited in text paragraph, it is enclosed in angle + brackets to remind the reader the reference in the synopsis section. + For better visibility, the placeholder is typeset in italics: + The _<file>_ to be added. + Possibility of multiple occurrences is indicated by three dots: <file>... (One or more of <file>.) @@ -751,6 +785,8 @@ Writing Documentation: Incorrect: `\--pretty=oneline` +A placeholder is not enclosed in backticks, as it is not a literal. + If some place in the documentation needs to typeset a command usage example with inline substitutions, it is fine to use +monospaced and inline substituted text+ instead of `monospaced literal text`, and with diff --git a/Documentation/Makefile b/Documentation/Makefile index b629176d7d..3f2383a12c 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -122,6 +122,7 @@ TECH_DOCS += technical/scalar TECH_DOCS += technical/send-pack-pipeline TECH_DOCS += technical/shallow TECH_DOCS += technical/trivial-merge +TECH_DOCS += technical/unit-tests SP_ARTICLES += $(TECH_DOCS) SP_ARTICLES += technical/api-index diff --git a/Documentation/MyFirstContribution.txt b/Documentation/MyFirstContribution.txt index 7cfed60c2e..f06563e981 100644 --- a/Documentation/MyFirstContribution.txt +++ b/Documentation/MyFirstContribution.txt @@ -35,8 +35,9 @@ announcements, design discussions, and more take place. Those interested in contributing are welcome to post questions here. The Git list requires plain-text-only emails and prefers inline and bottom-posting when replying to mail; you will be CC'd in all replies to you. Optionally, you can subscribe to -the list by sending an email to majordomo@vger.kernel.org with "subscribe git" -in the body. The https://lore.kernel.org/git[archive] of this mailing list is +the list by sending an email to <git+subscribe@vger.kernel.org> +(see https://subspace.kernel.org/subscribing.html for details). +The https://lore.kernel.org/git[archive] of this mailing list is available to view in a browser. ==== https://groups.google.com/forum/#!forum/git-mentoring[git-mentoring@googlegroups.com] @@ -833,7 +834,7 @@ Johannes Schindelin to make life as a Git contributor easier for those used to the GitHub PR workflow. It allows contributors to open pull requests against its mirror of the Git project, and does some magic to turn the PR into a set of emails and send them out for you. It also runs the Git continuous integration -suite for you. It's documented at http://gitgitgadget.github.io. +suite for you. It's documented at https://gitgitgadget.github.io/. [[create-fork]] === Forking `git/git` on GitHub diff --git a/Documentation/RelNotes/1.6.2.txt b/Documentation/RelNotes/1.6.2.txt index 980adfb315..166d73c60f 100644 --- a/Documentation/RelNotes/1.6.2.txt +++ b/Documentation/RelNotes/1.6.2.txt @@ -10,7 +10,7 @@ To ease the transition plan, the receiving repository of such a push running this release will issue a big warning when the configuration variable is missing. Please refer to: - http://git.or.cz/gitwiki/GitFaq#non-bare + https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/GitFaq.html#non-bare https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the diff --git a/Documentation/RelNotes/1.6.3.txt b/Documentation/RelNotes/1.6.3.txt index 4bcff945e0..bbf177fc3c 100644 --- a/Documentation/RelNotes/1.6.3.txt +++ b/Documentation/RelNotes/1.6.3.txt @@ -10,7 +10,7 @@ To ease the transition plan, the receiving repository of such a push running this release will issue a big warning when the configuration variable is missing. Please refer to: - http://git.or.cz/gitwiki/GitFaq#non-bare + https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/GitFaq.html#non-bare https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the diff --git a/Documentation/RelNotes/1.6.4.txt b/Documentation/RelNotes/1.6.4.txt index a2a34b43a7..0fccfb0bf0 100644 --- a/Documentation/RelNotes/1.6.4.txt +++ b/Documentation/RelNotes/1.6.4.txt @@ -10,7 +10,7 @@ To ease the transition plan, the receiving repository of such a push running this release will issue a big warning when the configuration variable is missing. Please refer to: - http://git.or.cz/gitwiki/GitFaq#non-bare + https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/GitFaq.html#non-bare https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the diff --git a/Documentation/RelNotes/1.6.5.txt b/Documentation/RelNotes/1.6.5.txt index 6c7f7da7eb..79cb1b2b6d 100644 --- a/Documentation/RelNotes/1.6.5.txt +++ b/Documentation/RelNotes/1.6.5.txt @@ -21,7 +21,7 @@ To ease the transition plan, the receiving repository of such a push running this release will issue a big warning when the configuration variable is missing. Please refer to: - http://git.or.cz/gitwiki/GitFaq#non-bare + https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/GitFaq.html#non-bare https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the diff --git a/Documentation/RelNotes/1.6.6.txt b/Documentation/RelNotes/1.6.6.txt index 3ed1e01433..88b86a827e 100644 --- a/Documentation/RelNotes/1.6.6.txt +++ b/Documentation/RelNotes/1.6.6.txt @@ -63,7 +63,7 @@ users will fare this time. Please refer to: - http://git.or.cz/gitwiki/GitFaq#non-bare + https://archive.kernel.org/oldwiki/git.wiki.kernel.org/index.php/GitFaq.html#non-bare https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the diff --git a/Documentation/RelNotes/2.43.0.txt b/Documentation/RelNotes/2.43.0.txt index 770543c464..e0e5b535bb 100644 --- a/Documentation/RelNotes/2.43.0.txt +++ b/Documentation/RelNotes/2.43.0.txt @@ -10,8 +10,8 @@ Backward Compatibility Notes prefix. If you are negatively affected by this change, please use "--subject-prefix=PATCH --rfc" as a replacement. - * "git rev-list --stdin" learned to take non-revisions (like "--not") - recently from the standard input, but the way such a "--not" was + * In Git 2.42, "git rev-list --stdin" learned to take non-revisions + (like "--not") from the standard input, but the way such a "--not" was handled was quite confusing, which has been rethought. The updated rule is that "--not" given from the command line only affects revs given from the command line that comes but not revs read from the @@ -22,10 +22,11 @@ Backward Compatibility Notes UI, Workflows & Features * A message written in olden time prevented a branch from getting - checked out saying it is already checked out elsewhere, but these + checked out, saying it is already checked out elsewhere. But these days, we treat a branch that is being bisected or rebased just like - a branch that is checked out and protect it. Rephrase the message - to say that the branch is in use. + a branch that is checked out and protect it from getting modified + with the same codepath. The message has been rephrased to say that + the branch is "in use" to avoid confusion. * Hourly and other schedules of "git maintenance" jobs are randomly distributed now. @@ -43,20 +44,21 @@ UI, Workflows & Features * Git GUI updates. - * "git format-patch" learns a way to feed cover letter description, - that (1) can be used on detached HEAD where there is no branch - description available, and (2) also can override the branch - description if there is one. + * "git format-patch" learned a new "--description-file" option that + lets cover letter description to be fed; this can be used on + detached HEAD where there is no branch description available, and + also can override the branch description if there is one. - * Use of --max-pack-size to allow multiple packfiles to be created is - now supported even when we are sending unreachable objects to cruft - packs. + * Use of the "--max-pack-size" option to allow multiple packfiles to + be created is now supported even when we are sending unreachable + objects to cruft packs. * "git format-patch --rfc --subject-prefix=<foo>" used to ignore the "--subject-prefix" option and used "[RFC PATCH]"; now we will add "RFC" prefix to whatever subject prefix is specified. - * "git log --format" has been taught the %(decorate) placeholder. + * "git log --format" has been taught the %(decorate) placeholder for + further customization over what the "--decorate" option offers. * The default log message created by "git revert", when reverting a commit that records a revert, has been tweaked, to encourage people @@ -66,41 +68,45 @@ UI, Workflows & Features * The command-line completion support (in contrib/) learned to complete "git commit --trailer=" for possible trailer keys. - * "git update-index" learns "--show-index-version" to inspect - the index format version used by the on-disk index file. + * "git update-index" learned the "--show-index-version" option to + inspect the index format version used by the on-disk index file. - * "git diff" learned diff.statNameWidth configuration variable, to - give the default width for the name part in the "--stat" output. + * "git diff" learned the "diff.statNameWidth" configuration variable, + to give the default width for the name part in the "--stat" output. * "git range-diff --notes=foo" compared "log --notes=foo --notes" of - the two ranges, instead of using just the specified notes tree. + the two ranges, instead of using just the specified notes tree, + which has been corrected to use only the specified notes tree. * The command line completion script (in contrib/) can be told to complete aliases by including ": git <cmd> ;" in the alias to tell - it that the alias should be completed in a similar way to how "git <cmd>" is - completed. The parsing code for the alias has been loosened to - allow ';' without an extra space before it. + it that the alias should be completed in a similar way to how "git + <cmd>" is completed. The parsing code for the alias has been + loosened to allow ';' without an extra space before it. * "git for-each-ref" and friends learned to apply mailmap to - authorname and other fields. + authorname and other fields in a more flexible way than using + separate placeholder letters like %a[eElL] every time we want to + come up with small variants. - * "git repack" machinery learns to pay attention to the "--filter=" + * "git repack" machinery learned to pay attention to the "--filter=" option. - * "git repack" learned "--max-cruft-size" to prevent cruft packs from - growing without bounds. + * "git repack" learned the "--max-cruft-size" option to prevent cruft + packs from growing without bounds. * "git merge-tree" learned to take strategy backend specific options via the "-X" option, like "git merge" does. - * "git log" and friends learned "--dd" that is a short-hand for - "--diff-merges=first-parent -p". + * "git log" and friends learned the "--dd" option that is a + short-hand for "--diff-merges=first-parent -p". - * The attribute subsystem learned to honor `attr.tree` configuration - that specifies which tree to read the .gitattributes files from. + * The attribute subsystem learned to honor the "attr.tree" + configuration variable that specifies which tree to read the + .gitattributes files from. - * "git merge-file" learns a mode to read three contents to be merged - from blob objects. + * "git merge-file" learns a mode to read three variants of the + contents to be merged from blob objects. Performance, Internal Implementation, Development Support etc. @@ -110,7 +116,7 @@ Performance, Internal Implementation, Development Support etc. * It may be tempting to leave the help text NULL for a command line option that is either hidden or too obvious, but "git subcmd -h" and "git subcmd --help-all" would have segfaulted if done so. Now - the help text is optional. + the help text is truly optional. * Tests that are known to pass with LSan are now marked as such. @@ -122,7 +128,7 @@ Performance, Internal Implementation, Development Support etc. filtering the uninteresting output. * Unused parameters to functions are marked as such, and/or removed, - in order to bring us closer to -Wunused-parameter clean. + in order to bring us closer to "-Wunused-parameter" clean. * The code to keep track of existing packs in the repository while repacking has been refactored. @@ -161,10 +167,12 @@ Fixes since v2.42 non-zero generation numbers has been updated. * "git diff -w --exit-code" with various options did not work - correctly, which is being addressed. + correctly, which has been corrected. - * transfer.unpackLimit ought to be used as a fallback, but overrode - fetch.unpackLimit and receive.unpackLimit instead. + * The "transfer.unpackLimit" configuration variable ought to be used + as a fallback, but overrode the more specific "fetch.unpackLimit" + and "receive.unpackLimit" configuration variables by mistake, which + has been corrected. * The use of API between two calls to require_clean_work_tree() from the sequencer code has been cleaned up for consistency. @@ -172,22 +180,23 @@ Fixes since v2.42 * "git diff --no-such-option" and other corner cases around the exit status of the "diff" command have been corrected. - * "git for-each-ref --sort='contents:size'" sorts the refs according + * "git for-each-ref --sort='contents:size'" sorted the refs according to size numerically, giving a ref that points at a blob twelve-byte - (12) long before showing a blob hundred-byte (100) long. + (12) long before showing a blob hundred-byte (100) long, which has + been corrected. * We now limit the depth of the tree objects and maximum length of pathnames recorded in tree objects. (merge 4d5693ba05 jk/tree-name-and-depth-limit later to maint). - * Various fixes to the behavior of "rebase -i" when the command got - interrupted by conflicting changes. + * Various fixes to the behavior of "rebase -i", when the command got + interrupted by conflicting changes, have been made. * References from a description of the `--patch` option in various manual pages have been simplified and improved. * "git grep -e A --no-or -e B" is accepted, even though the negation - of "or" did not mean anything, which has been tightened. + of the "--or" option did not mean anything, which has been tightened. * The completion script (in contrib/) has been taught to treat the "-t" option to "git checkout" and "git switch" just like the @@ -196,23 +205,24 @@ Fixes since v2.42 * "git diff --no-index -R <(one) <(two)" did not work correctly, which has been corrected. - * Update "git maintenance" timers' implementation based on systemd - timers to work with WSL. + * "git maintenance" timers' implementation has been updated, based on + systemd timers, to work with WSL. * "git diff --cached" codepath did not fill the necessary stat information for a file when fsmonitor knows it is clean and ended - up behaving as if it is not clean, which has been corrected. + up behaving as if it were not clean, which has been corrected. - * Clarify how "alias.foo = : git cmd ; aliased-command-string" should be - spelled with necessary whitespace around punctuation marks to - work. + * How "alias.foo = : git cmd ; aliased-command-string" should be + spelled with necessary whitespace around punctuation marks to work + has been more clearly documented (but this will be moot with newer + versions of Git where the parsing rules have been improved). * HTTP Header redaction code has been adjusted for a newer version of cURL library that shows its traces differently from earlier versions. - * An error message given by "git send-email" when given a malformed - address did not give correct information, which has been corrected. + * An error message given by "git send-email", when given a malformed + address, did not show the offending address, which has been corrected. * UBSan options were not propagated through the test framework to git run via the httpd, unlike ASan options, which has been corrected. @@ -229,9 +239,9 @@ Fixes since v2.42 * Update mailmap entry for Derrick. (merge 6e5457d8c7 ds/mailmap-entry-update later to maint). - * In .gitmodules files, submodules are keyed by their names, and the - path to the submodule whose name is $name is specified by the - submodule.$name.path variable. There were a few codepaths that + * In the ".gitmodules" files, submodules are keyed by their names, + and the path to the submodule whose name is $name is specified by + the submodule.$name.path variable. There were a few codepaths that mixed the name and path up when consulting the submodule database, which have been corrected. It took long for these bugs to be found as the name of a submodule initially is the same as its path, and @@ -244,8 +254,8 @@ Fixes since v2.42 corrected. (merge 4adceb5a29 ar/diff-index-merge-base-fix later to maint). - * Fix "git merge-tree" to stop segfaulting when the --attr-source - option is used. + * "git merge-tree" used to segfault when the "--attr-source" + option is used, which has been corrected. (merge e95bafc52f jc/merge-ort-attr-index-fix later to maint). * Unlike "git log --pretty=%D", "git log --pretty="%(decorate)" did @@ -276,7 +286,6 @@ Fixes since v2.42 the top level of the working tree; it has been corrected to read "sub/patterns" instead. - * "git reflog expire --single-worktree" has been broken for the past 20 months or so, which has been corrected. @@ -300,6 +309,10 @@ Fixes since v2.42 non-commit objects, which has been corrected. (merge 7b3c8e9f38 tb/rev-list-unpacked-fix later to maint). + * "To dereference" and "to peel" were sometimes used in in-code + comments and documentation but without description in the glossary. + (merge 893dce2ffb vd/glossary-dereference-peel later to maint). + * Other code cleanup, docfix, build fix, etc. (merge c2c349a15c xz/commit-title-soft-limit-doc later to maint). (merge 1bd809938a tb/format-pack-doc-update later to maint). @@ -307,3 +320,4 @@ Fixes since v2.42 (merge 3ca86adc2d la/strvec-header-fix later to maint). (merge 6789275d37 jc/test-i18ngrep later to maint). (merge 9972cd6004 ps/leakfixes later to maint). + (merge 46edab516b tz/send-email-helpfix later to maint). diff --git a/Documentation/RelNotes/2.43.1.txt b/Documentation/RelNotes/2.43.1.txt new file mode 100644 index 0000000000..20e96f2dfa --- /dev/null +++ b/Documentation/RelNotes/2.43.1.txt @@ -0,0 +1,82 @@ +Git 2.43.1 Release Notes +======================== + +There is nothing exciting to see here. Relative to Git 2.43, this +release contains the fixes that have already been merged to the +'master' branch of the development towards the next major release. + +Fixes since Git 2.43.0 +---------------------- + + * The way CI testing used "prove" could lead to running the test + suite twice needlessly, which has been corrected. + + * Newer versions of Getopt::Long started giving warnings against our + (ab)use of it in "git send-email". Bump the minimum version + requirement for Perl to 5.8.1 (from September 2002) to allow + simplifying our implementation. + + * Earlier we stopped relying on commit-graph that (still) records + information about commits that are lost from the object store, + which has negative performance implications. The default has been + flipped to disable this pessimization. + + * Stale URLs have been updated to their current counterparts (or + archive.org) and HTTP links are replaced with working HTTPS links. + + * trace2 streams used to record the URLs that potentially embed + authentication material, which has been corrected. + + * The sample pre-commit hook that tries to catch introduction of new + paths that use potentially non-portable characters did not notice + an existing path getting renamed to such a problematic path, when + rename detection was enabled. + + * The command line parser for the "log" family of commands was too + loose when parsing certain numbers, e.g., silently ignoring the + extra 'q' in "git log -n 1q" without complaining, which has been + tightened up. + + * "git $cmd --end-of-options --rev -- --path" for some $cmd failed + to interpret "--rev" as a rev, and "--path" as a path. This was + fixed for many programs like "reset" and "checkout". + + * "git bisect reset" has been taught to clean up state files and refs + even when BISECT_START file is gone. + + * Some codepaths did not correctly parse configuration variables + specified with valueless "true", which has been corrected. + + * Code clean-up for sanity checking of command line options for "git + show-ref". + + * The code to parse the From e-mail header has been updated to avoid + recursion. + + * "git fetch --atomic" issued an unnecessary empty error message, + which has been corrected. + + * Command line completion script (in contrib/) learned to work better + with the reftable backend. + + * "git status" is taught to show both the branch being bisected and + being rebased when both are in effect at the same time. + cf. <xmqqil76kyov.fsf@gitster.g> + + * "git archive --list extra garbage" silently ignored excess command + line parameters, which has been corrected. + + * "git sparse-checkout set" added default patterns even when the + patterns are being fed from the standard input, which has been + corrected. + + * Unlike other environment variables that took the usual + true/false/yes/no as well as 0/1, GIT_FLUSH only understood 0/1, + which has been corrected. + + * Clearing in-core repository (happens during e.g., "git fetch + --recurse-submodules" with commit graph enabled) made in-core + commit object in an inconsistent state by discarding the necessary + data from commit-graph too early, which has been corrected. + +Also contains various documentation updates, code clean-ups and minor fixups. diff --git a/Documentation/RelNotes/2.43.2.txt b/Documentation/RelNotes/2.43.2.txt new file mode 100644 index 0000000000..5895e23a54 --- /dev/null +++ b/Documentation/RelNotes/2.43.2.txt @@ -0,0 +1,37 @@ +Git 2.43.2 Release Notes +======================== + +Relative to Git 2.43.1, this release has two important fixes to allow +"git imap-send" to be built with NO_CURL defined, and to restore the +forced flushing behaviour when GIT_FLUSH=1 is set. It also contains +other, unexciting, fixes that have already been merged to the 'master' +branch of the development towards the next major release. + +Fixes since Git 2.43.1 +---------------------- + + * Update to a new feature recently added, "git show-ref --exists". + + * Rename detection logic ignored the final line of a file if it is an + incomplete line. + + * "git diff --no-rename A B" did not disable rename detection but did + not trigger an error from the command line parser. + + * "git diff --no-index file1 file2" segfaulted while invoking the + external diff driver, which has been corrected. + + * Rewrite //-comments to /* comments */ in files whose comments + prevalently use the latter. + + * A failed "git tag -s" did not necessarily result in an error + depending on the crypto backend, which has been corrected. + + * "git stash" sometimes was silent even when it failed due to + unwritable index file, which has been corrected. + + * Recent conversion to allow more than 0/1 in GIT_FLUSH broke the + mechanism by flipping what yes/no means by mistake, which has been + corrected. + +Also contains documentation updates, code clean-ups and minor fixups. diff --git a/Documentation/RelNotes/2.43.3.txt b/Documentation/RelNotes/2.43.3.txt new file mode 100644 index 0000000000..924f20594f --- /dev/null +++ b/Documentation/RelNotes/2.43.3.txt @@ -0,0 +1,12 @@ +Git 2.43.3 Release Notes +======================== + +Relative to Git 2.43.2, this release fixes one regression that +manifests while running "git commit -v --trailer". + +Fixes since Git 2.43.2 +---------------------- + + * "git commit -v --trailer=..." was broken with recent update and + placed the trailer _after_ the divider line, which has been + corrected. diff --git a/Documentation/RelNotes/2.44.0.txt b/Documentation/RelNotes/2.44.0.txt new file mode 100644 index 0000000000..14f9ce8226 --- /dev/null +++ b/Documentation/RelNotes/2.44.0.txt @@ -0,0 +1,334 @@ +Git v2.44 Release Notes +======================= + +Backward Compatibility Notes + + * "git checkout -B <branch>" used to allow switching to a branch that + is in use on another worktree, but this was by mistake. The users + need to use "--ignore-other-worktrees" option. + + +UI, Workflows & Features + + * "git add" and "git stash" learned to support the ":(attr:...)" + magic pathspec. + + * "git rebase --autosquash" is now enabled for non-interactive rebase, + but it is still incompatible with the apply backend. + + * Introduce "git replay", a tool meant on the server side without + working tree to recreate a history. + + * "git merge-file" learned to take the "--diff-algorithm" option to + use algorithm different from the default "myers" diff. + + * Command line completion (in contrib/) learned to complete path + arguments to the "add/set" subcommands of "git sparse-checkout" + better. + + * "git checkout -B <branch> [<start-point>]" allowed a branch that is + in use in another worktree to be updated and checked out, which + might be a bit unexpected. The rule has been tightened, which is a + breaking change. "--ignore-other-worktrees" option is required to + unbreak you, if you are used to the current behaviour that "-B" + overrides the safety. + + * The builtin_objectmode attribute is populated for each path + without adding anything in .gitattributes files, which would be + useful in magic pathspec, e.g., ":(attr:builtin_objectmode=100755)" + to limit to executables. + + * "git fetch" learned to pay attention to "fetch.all" configuration + variable, which pretends as if "--all" was passed from the command + line when no remote parameter was given. + + * In addition to (rather cryptic) Security Identifiers, show username + and domain in the error message when we barf on mismatch between + the Git directory and the current user on Windows. + + * The error message given when "git branch -d branch" fails due to + commits unique to the branch has been split into an error and a new + conditional advice message. + + * When given an existing but unreadable file as a configuration file, + gitweb behaved as if the file did not exist at all, but now it + errors out. This is a change that may break backward compatibility. + + * When $HOME/.gitconfig is missing but XDG config file is available, we + should write into the latter, not former. "git gc" and "git + maintenance" wrote into a wrong "global config" file, which have + been corrected. + + * Define "special ref" as a very narrow set that consists of + FETCH_HEAD and MERGE_HEAD, and clarify everything else that used to + be classified as such are actually just pseudorefs. + + * All conditional "advice" messages show how to turn them off, which + becomes repetitive. Setting advice.* configuration explicitly on + now omits the instruction part. + + * The "disable repository discovery of a bare repository" check, + triggered by setting safe.bareRepository configuration variable to + 'explicit', has been loosened to exclude the ".git/" directory inside + a non-bare repository from the check. So you can do "cd .git && + git cmd" to run a Git command that works on a bare repository without + explicitly specifying $GIT_DIR now. + + * The completion script (in contrib/) learned more options that can + be used with "git log". + + * The labels on conflict markers for the common ancestor, our version, + and the other version are available to custom 3-way merge driver + via %S, %X, and %Y placeholders. + + * The write codepath for the reftable data learned to honor + core.fsync configuration. + + * The "--fsck-objects" option of "git index-pack" now can take the + optional parameter to tweak severity of different fsck errors. + + * The wincred credential backend has been taught to support oauth + refresh token the same way as credential-cache and + credential-libsecret backends. + + * Command line completion support (in contrib/) has been + updated for "git bisect". + + * "git branch" and friends learned to use the formatted text as + sorting key, not the underlying timestamp value, when the --sort + option is used with author or committer timestamp with a format + specifier (e.g., "--sort=creatordate:format:%H:%M:%S"). + + * The command line completion script (in contrib/) learned to + complete configuration variable names better. + + +Performance, Internal Implementation, Development Support etc. + + * Process to add some form of low-level unit tests has started. + + * Add support for GitLab CI. + + * "git for-each-ref --no-sort" still sorted the refs alphabetically + which paid non-trivial cost. It has been redefined to show output + in an unspecified order, to allow certain optimizations to take + advantage of. + + * Simplify API implementation to delete references by eliminating + duplication. + + * Subject approxidate() and show_date() machinery to OSS-Fuzz. + + * A new helper to let us pretend that we called lstat() when we know + our cache_entry is up-to-date via fsmonitor. + + * The optimization based on fsmonitor in the "diff --cached" + codepath is resurrected with the "fake-lstat" introduced earlier. + + * Test balloon to use C99 "bool" type from <stdbool.h> has been + added. + + * "git clone" has been prepared to allow cloning a repository with + non-default hash function into a repository that uses the reftable + backend. + + * Streaming spans of packfile data used to be done only from a + single, primary, pack in a repository with multiple packfiles. It + has been extended to allow reuse from other packfiles, too. + + * Comment updates to help developers not to attempt to modify + messages from plumbing commands that must stay constant. + + It might make sense to reassess the plumbing needs every few years, + but that should be done as a separate effort. + + * Move test-ctype helper to the unit-test framework. + + * Instead of manually creating refs/ hierarchy on disk upon a + creation of a secondary worktree, which is only usable via the + files backend, use the refs API to populate it. + + * CI for GitLab learned to drive macOS jobs. + + * A few tests to "git commit -o <pathspec>" and "git commit -i + <pathspec>" has been added. + + * Tests on ref API are moved around to prepare for reftable. + + * The Makefile often had to say "-L$(path) -R$(path)" that repeats + the path to the same library directory for link time and runtime. + A Makefile template is used to reduce such repetition. + + * The priority queue test has been migrated to the unit testing + framework. + + * Setting `feature.experimental` opts the user into multi-pack reuse + experiment + + * Squelch node.js 16 deprecation warnings from GitHub Actions CI + by updating actions/github-script and actions/checkout that use + node.js 20. + + * The mechanism to report the filename in the source code, used by + the unit-test machinery, assumed that the compiler expanded __FILE__ + to the path to the source given to the $(CC), but some compilers + give full path, breaking the output. This has been corrected. + + +Fixes since v2.43 +----------------- + + * The way CI testing used "prove" could lead to running the test + suite twice needlessly, which has been corrected. + + * Update ref-related tests. + + * "git format-patch --encode-email-headers" ignored the option when + preparing the cover letter, which has been corrected. + + * Newer versions of Getopt::Long started giving warnings against our + (ab)use of it in "git send-email". Bump the minimum version + requirement for Perl to 5.8.1 (from September 2002) to allow + simplifying our implementation. + + * Earlier we stopped relying on commit-graph that (still) records + information about commits that are lost from the object store, + which has negative performance implications. The default has been + flipped to disable this pessimization. + + * Stale URLs have been updated to their current counterparts (or + archive.org) and HTTP links are replaced with working HTTPS links. + + * trace2 streams used to record the URLs that potentially embed + authentication material, which has been corrected. + + * The sample pre-commit hook that tries to catch introduction of new + paths that use potentially non-portable characters did not notice + an existing path getting renamed to such a problematic path, when + rename detection was enabled. + + * The command line parser for the "log" family of commands was too + loose when parsing certain numbers, e.g., silently ignoring the + extra 'q' in "git log -n 1q" without complaining, which has been + tightened up. + + * "git $cmd --end-of-options --rev -- --path" for some $cmd failed + to interpret "--rev" as a rev, and "--path" as a path. This was + fixed for many programs like "reset" and "checkout". + + * "git bisect reset" has been taught to clean up state files and refs + even when BISECT_START file is gone. + + * Some codepaths did not correctly parse configuration variables + specified with valueless "true", which has been corrected. + + * Code clean-up for sanity checking of command line options for "git + show-ref". + + * The code to parse the From e-mail header has been updated to avoid + recursion. + + * "git fetch --atomic" issued an unnecessary empty error message, + which has been corrected. + + * Command line completion script (in contrib/) learned to work better + with the reftable backend. + + * "git status" is taught to show both the branch being bisected and + being rebased when both are in effect at the same time. + + * "git archive --list extra garbage" silently ignored excess command + line parameters, which has been corrected. + + * "git sparse-checkout set" added default patterns even when the + patterns are being fed from the standard input, which has been + corrected. + + * "git sparse-checkout (add|set) --[no-]cone --end-of-options" did + not handle "--end-of-options" correctly after a recent update. + + * Unlike other environment variables that took the usual + true/false/yes/no as well as 0/1, GIT_FLUSH only understood 0/1, + which has been corrected. + + * Clearing in-core repository (happens during e.g., "git fetch + --recurse-submodules" with commit graph enabled) made in-core + commit object in an inconsistent state by discarding the necessary + data from commit-graph too early, which has been corrected. + + * Update to a new feature recently added, "git show-ref --exists". + + * oss-fuzz tests are built and run in CI. + (merge c4a9cf1df3 js/oss-fuzz-build-in-ci later to maint). + + * Rename detection logic ignored the final line of a file if it is an + incomplete line. + + * GitHub CI update. + (merge 0188b2c8e0 pb/ci-github-skip-logs-for-broken-tests later to maint). + + * "git diff --no-rename A B" did not disable rename detection but did + not trigger an error from the command line parser. + + * "git archive --remote=<remote>" learned to talk over the smart + http (aka stateless) transport. + (merge 176cd68634 jx/remote-archive-over-smart-http later to maint). + + * Fetching via protocol v0 over Smart HTTP transport sometimes failed + to correctly auto-follow tags. + (merge fba732c462 jk/fetch-auto-tag-following-fix later to maint). + + * The documentation for the --exclude-per-directory option marked it + as deprecated, which confused readers into thinking there may be a + plan to remove it in the future, which was not our intention. + (merge 0009542cab jc/ls-files-doc-update later to maint). + + * "git diff --no-index file1 file2" segfaulted while invoking the + external diff driver, which has been corrected. + + * Rewrite //-comments to /* comments */ in files whose comments + prevalently use the latter. + + * Cirrus CI jobs started breaking because we specified version of + FreeBSD that is no longer available, which has been corrected. + (merge 81fffb66d3 cb/use-freebsd-13-2-at-cirrus-ci later to maint). + + * A caller called index_file_exists() that takes a string expressed + as <ptr, length> with a wrong length, which has been corrected. + (merge 156e28b36d jh/sparse-index-expand-to-path-fix later to maint). + + * A failed "git tag -s" did not necessarily result in an error + depending on the crypto backend, which has been corrected. + + * "git stash" sometimes was silent even when it failed due to + unwritable index file, which has been corrected. + + * "git show-ref --verify" did not show things like "CHERRY_PICK_HEAD", + which has been corrected. + + * Recent conversion to allow more than 0/1 in GIT_FLUSH broke the + mechanism by flipping what yes/no means by mistake, which has been + corrected. + + * The sequencer machinery does not use the ref API and instead + records names of certain objects it needs for its correct operation + in temporary files, which makes these objects susceptible to loss + by garbage collection. These temporary files have been added as + starting points for reachability analysis to fix this. + (merge bc7f5db896 pw/gc-during-rebase later to maint). + + * "git cherry-pick" invoked during "git rebase -i" session lost + the authorship information, which has been corrected. + (merge e4301f73ff vn/rebase-with-cherry-pick-authorship later to maint). + + * The code paths that call repo_read_object_file() have been + tightened to react to errors. + (merge 568459bf5e js/check-null-from-read-object-file later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 5aea3955bc rj/clarify-branch-doc-m later to maint). + (merge 9cce3be2df bk/bisect-doc-fix later to maint). + (merge 8430b438f6 vd/fsck-submodule-url-test later to maint). + (merge 3cb4384683 jc/t0091-with-unknown-git later to maint). + (merge 020456cb74 rs/receive-pack-remove-find-header later to maint). + (merge bc47139f4f la/trailer-cleanups later to maint). diff --git a/Documentation/RelNotes/2.45.0.txt b/Documentation/RelNotes/2.45.0.txt new file mode 100644 index 0000000000..321da04ddd --- /dev/null +++ b/Documentation/RelNotes/2.45.0.txt @@ -0,0 +1,76 @@ +Git v2.45 Release Notes +======================= + +Backward Compatibility Notes + +UI, Workflows & Features + + * Integrate the reftable code into the refs framework as a backend. + With "git init --ref-format=reftable", hopefully it would be a lot + more efficient to manage a repository with many references. + + * "git checkout -p" and friends learned that that "@" is a synonym + for "HEAD". + + * Variants of vimdiff learned to honor mergetool.<variant>.layout + settings. + + * "git reflog" learned a "list" subcommand that enumerates known reflogs. + + +Performance, Internal Implementation, Development Support etc. + + * The code to iterate over refs with the reftable backend has seen + some optimization. + + * More tests that are marked as "ref-files only" have been updated to + improve test coverage of reftable backend. + + * Some parts of command line completion script (in contrib/) have + been micro-optimized. + + * The way placeholders are to be marked-up in documentation have been + specified; use "_<placeholder>_" to typeset the word inside a pair + of <angle-brakets> emphasized. + + +Fixes since v2.44 +----------------- + + * "git apply" on a filesystem without filemode support have learned + to take a hint from what is in the index for the path, even when + not working with the "--index" or "--cached" option, when checking + the executable bit match what is required by the preimage in the + patch. + (merge 45b625142d cp/apply-core-filemode later to maint). + + * "git column" has been taught to reject negative padding value, as + it would lead to nonsense behaviour including division by zero. + (merge 76fb807faa kh/column-reject-negative-padding later to maint). + + * "git am --help" now tells readers what actions are available in + "git am --whitespace=<action>", in addition to saying that the + option is passed through to the underlying "git apply". + (merge a171dac734 jc/am-whitespace-doc later to maint). + + * "git tag --column" failed to check the exit status of its "git + column" invocation, which has been corrected. + (merge 92e66478fc rj/tag-column-fix later to maint). + + * Credential helper based on libsecret (in contrib/) has been updated + to handle an empty password correctly. + (merge 8f1f2023b7 mh/libsecret-empty-password-fix later to maint). + + * "git difftool --dir-diff" learned to honor the "--trust-exit-code" + option; it used to always exit with 0 and signalled success. + (merge eb84c8b6ce ps/difftool-dir-diff-exit-code later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge f0e578c69c rs/use-xstrncmpz later to maint). + (merge 83e6eb7d7a ba/credential-test-clean-fix later to maint). + (merge 64562d784d jb/doc-interactive-singlekey-do-not-need-perl later to maint). + (merge c431a235e2 cp/t9146-use-test-path-helpers later to maint). + (merge 82d75402d5 ds/doc-send-email-capitalization later to maint). + (merge 41bff66e35 jc/doc-add-placeholder-fix later to maint). + (merge 6835f0efe9 jw/remote-doc-typofix later to maint). + (merge 244001aa20 hs/rebase-not-in-progress later to maint). diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index bce7f97815..e734a3f0f1 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -355,9 +355,21 @@ If you like, you can put extra tags at the end: patch after a detailed analysis. . `Tested-by:` is used to indicate that the person applied the patch and found it to have the desired effect. - -You can also create your own tag or use one that's in common usage -such as "Thanks-to:", "Based-on-patch-by:", or "Mentored-by:". +. `Co-authored-by:` is used to indicate that people exchanged drafts + of a patch before submitting it. +. `Helped-by:` is used to credit someone who suggested ideas for + changes without providing the precise changes in patch form. +. `Mentored-by:` is used to credit someone with helping develop a + patch as part of a mentorship program (e.g., GSoC or Outreachy). +. `Suggested-by:` is used to credit someone with suggesting the idea + for a patch. + +While you can also create your own trailer if the situation warrants it, we +encourage you to instead use one of the common trailers in this project +highlighted above. + +Only capitalize the very first letter of tags, i.e. favor +"Signed-off-by" over "Signed-Off-By" and "Acked-by:" over "Acked-By". [[git-tools]] === Generate your patch using Git tools out of your commits. @@ -570,7 +582,7 @@ their trees themselves. master). * Read the Git mailing list, the maintainer regularly posts messages - entitled "What's cooking in git.git" and "What's in git.git" giving + entitled "What's cooking in git.git" giving the status of various proposed changes. == GitHub CI[[GHCI]] @@ -590,11 +602,12 @@ After the initial setup, CI will run whenever you push new changes to your fork of Git on GitHub. You can monitor the test state of all your branches here: `https://github.com/<Your GitHub handle>/git/actions/workflows/main.yml` -If a branch did not pass all test cases then it is marked with a red -cross. In that case you can click on the failing job and navigate to -"ci/run-build-and-tests.sh" and/or "ci/print-test-failures.sh". You -can also download "Artifacts" which are tarred (or zipped) archives -with test data relevant for debugging. +If a branch does not pass all test cases then it will be marked with a +red +x+, instead of a green check. In that case, you can click on the +failing job and navigate to "ci/run-build-and-tests.sh" and/or +"ci/print-test-failures.sh". You can also download "Artifacts" which +are zip archives containing tarred (or zipped) archives with test data +relevant for debugging. Then fix the problem and push your fix to your GitHub fork. This will trigger a new CI build to ensure all tests pass. @@ -686,7 +699,7 @@ message to an external program, and this is a handy way to drive `git am`. However, if the message is MIME encoded, what is piped into the program is the representation you see in your `*Article*` buffer after unwrapping MIME. This is often not what -you would want for two reasons. It tends to screw up non ASCII +you would want for two reasons. It tends to screw up non-ASCII characters (most notably in people's names), and also whitespaces (fatal in patches). Running "C-u g" to display the message in raw form before using "|" to run the pipe can work diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt index 2737381a11..dde8e7840e 100644 --- a/Documentation/config/advice.txt +++ b/Documentation/config/advice.txt @@ -1,30 +1,63 @@ advice.*:: These variables control various optional help messages designed to - aid new users. All 'advice.*' variables default to 'true', and you - can tell Git that you do not need help by setting these to 'false': + aid new users. When left unconfigured, Git will give the message + alongside instructions on how to squelch it. You can tell Git + that you do not need the help message by setting these to 'false': + -- + addEmbeddedRepo:: + Advice on what to do when you've accidentally added one + git repo inside of another. + addEmptyPathspec:: + Advice shown if a user runs the add command without providing + the pathspec parameter. + addIgnoredFile:: + Advice shown if a user attempts to add an ignored file to + the index. + amWorkDir:: + Advice that shows the location of the patch file when + linkgit:git-am[1] fails to apply it. ambiguousFetchRefspec:: Advice shown when a fetch refspec for multiple remotes maps to the same remote-tracking branch namespace and causes branch tracking set-up to fail. + checkoutAmbiguousRemoteBranchName:: + Advice shown when the argument to + linkgit:git-checkout[1] and linkgit:git-switch[1] + ambiguously resolves to a + remote tracking branch on more than one remote in + situations where an unambiguous argument would have + otherwise caused a remote-tracking branch to be + checked out. See the `checkout.defaultRemote` + configuration variable for how to set a given remote + to be used by default in some situations where this + advice would be printed. + commitBeforeMerge:: + Advice shown when linkgit:git-merge[1] refuses to + merge to avoid overwriting local changes. + detachedHead:: + Advice shown when you used + linkgit:git-switch[1] or linkgit:git-checkout[1] + to move to the detached HEAD state, to instruct how to + create a local branch after the fact. + diverging:: + Advice shown when a fast-forward is not possible. fetchShowForcedUpdates:: Advice shown when linkgit:git-fetch[1] takes a long time to calculate forced updates after ref updates, or to warn that the check is disabled. - pushUpdateRejected:: - Set this variable to 'false' if you want to disable - 'pushNonFFCurrent', 'pushNonFFMatching', 'pushAlreadyExists', - 'pushFetchFirst', 'pushNeedsForce', and 'pushRefNeedsUpdate' - simultaneously. - pushNonFFCurrent:: - Advice shown when linkgit:git-push[1] fails due to a - non-fast-forward update to the current branch. - pushNonFFMatching:: - Advice shown when you ran linkgit:git-push[1] and pushed - 'matching refs' explicitly (i.e. you used ':', or - specified a refspec that isn't your current branch) and - it resulted in a non-fast-forward error. + forceDeleteBranch:: + Advice shown when a user tries to delete a not fully merged + branch without the force option set. + ignoredHook:: + Advice shown if a hook is ignored because the hook is not + set as executable. + implicitIdentity:: + Advice on how to set your identity configuration when + your information is guessed from the system username and + domain name. + nestedTag:: + Advice shown if a user attempts to recursively tag a tag object. pushAlreadyExists:: Shown when linkgit:git-push[1] rejects an update that does not qualify for fast-forwarding (e.g., a tag.) @@ -37,6 +70,18 @@ advice.*:: tries to overwrite a remote ref that points at an object that is not a commit-ish, or make the remote ref point at an object that is not a commit-ish. + pushNonFFCurrent:: + Advice shown when linkgit:git-push[1] fails due to a + non-fast-forward update to the current branch. + pushNonFFMatching:: + Advice shown when you ran linkgit:git-push[1] and pushed + 'matching refs' explicitly (i.e. you used ':', or + specified a refspec that isn't your current branch) and + it resulted in a non-fast-forward error. + pushRefNeedsUpdate:: + Shown when linkgit:git-push[1] rejects a forced update of + a branch when its remote-tracking ref has updates that we + do not have locally. pushUnqualifiedRefname:: Shown when linkgit:git-push[1] gives up trying to guess based on the source and destination refs what @@ -44,10 +89,23 @@ advice.*:: we can still suggest that the user push to either refs/heads/* or refs/tags/* based on the type of the source object. - pushRefNeedsUpdate:: - Shown when linkgit:git-push[1] rejects a forced update of - a branch when its remote-tracking ref has updates that we - do not have locally. + pushUpdateRejected:: + Set this variable to 'false' if you want to disable + 'pushNonFFCurrent', 'pushNonFFMatching', 'pushAlreadyExists', + 'pushFetchFirst', 'pushNeedsForce', and 'pushRefNeedsUpdate' + simultaneously. + resetNoRefresh:: + Advice to consider using the `--no-refresh` option to + linkgit:git-reset[1] when the command takes more than 2 seconds + to refresh the index after reset. + resolveConflict:: + Advice shown by various commands when conflicts + prevent the operation from being performed. + rmHints:: + In case of failure in the output of linkgit:git-rm[1], + show directions on how to proceed from the current state. + sequencerInUse:: + Advice shown when a sequencer command is already in progress. skippedCherryPicks:: Shown when linkgit:git-rebase[1] skips a commit that has already been cherry-picked onto the upstream branch. @@ -68,78 +126,27 @@ advice.*:: Advise to consider using the `-u` option to linkgit:git-status[1] when the command takes more than 2 seconds to enumerate untracked files. - commitBeforeMerge:: - Advice shown when linkgit:git-merge[1] refuses to - merge to avoid overwriting local changes. - resetNoRefresh:: - Advice to consider using the `--no-refresh` option to - linkgit:git-reset[1] when the command takes more than 2 seconds - to refresh the index after reset. - resolveConflict:: - Advice shown by various commands when conflicts - prevent the operation from being performed. - sequencerInUse:: - Advice shown when a sequencer command is already in progress. - implicitIdentity:: - Advice on how to set your identity configuration when - your information is guessed from the system username and - domain name. - detachedHead:: - Advice shown when you used - linkgit:git-switch[1] or linkgit:git-checkout[1] - to move to the detached HEAD state, to instruct how to - create a local branch after the fact. - suggestDetachingHead:: - Advice shown when linkgit:git-switch[1] refuses to detach HEAD - without the explicit `--detach` option. - checkoutAmbiguousRemoteBranchName:: - Advice shown when the argument to - linkgit:git-checkout[1] and linkgit:git-switch[1] - ambiguously resolves to a - remote tracking branch on more than one remote in - situations where an unambiguous argument would have - otherwise caused a remote-tracking branch to be - checked out. See the `checkout.defaultRemote` - configuration variable for how to set a given remote - to be used by default in some situations where this - advice would be printed. - amWorkDir:: - Advice that shows the location of the patch file when - linkgit:git-am[1] fails to apply it. - rmHints:: - In case of failure in the output of linkgit:git-rm[1], - show directions on how to proceed from the current state. - addEmbeddedRepo:: - Advice on what to do when you've accidentally added one - git repo inside of another. - ignoredHook:: - Advice shown if a hook is ignored because the hook is not - set as executable. - waitingForEditor:: - Print a message to the terminal whenever Git is waiting for - editor input from the user. - nestedTag:: - Advice shown if a user attempts to recursively tag a tag object. submoduleAlternateErrorStrategyDie:: Advice shown when a submodule.alternateErrorStrategy option configured to "die" causes a fatal error. + submoduleMergeConflict:: + Advice shown when a non-trivial submodule merge conflict is + encountered. submodulesNotUpdated:: Advice shown when a user runs a submodule command that fails because `git submodule update --init` was not run. - addIgnoredFile:: - Advice shown if a user attempts to add an ignored file to - the index. - addEmptyPathspec:: - Advice shown if a user runs the add command without providing - the pathspec parameter. + suggestDetachingHead:: + Advice shown when linkgit:git-switch[1] refuses to detach HEAD + without the explicit `--detach` option. updateSparsePath:: Advice shown when either linkgit:git-add[1] or linkgit:git-rm[1] is asked to update index entries outside the current sparse checkout. - diverging:: - Advice shown when a fast-forward is not possible. + waitingForEditor:: + Print a message to the terminal whenever Git is waiting for + editor input from the user. worktreeAddOrphan:: Advice shown when a user tries to create a worktree from an - invalid reference, to instruct how to create a new orphan + invalid reference, to instruct how to create a new unborn branch instead. -- diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt index bd5ae0c337..6c7e09a1ef 100644 --- a/Documentation/config/diff.txt +++ b/Documentation/config/diff.txt @@ -223,5 +223,5 @@ diff.colorMoved:: diff.colorMovedWS:: When moved lines are colored using e.g. the `diff.colorMoved` setting, - this option controls the `<mode>` how spaces are treated - for details of valid modes see '--color-moved-ws' in linkgit:git-diff[1]. + this option controls the `<mode>` how spaces are treated. + For details of valid modes see '--color-moved-ws' in linkgit:git-diff[1]. diff --git a/Documentation/config/extensions.txt b/Documentation/config/extensions.txt index bccaec7a96..66db0e15da 100644 --- a/Documentation/config/extensions.txt +++ b/Documentation/config/extensions.txt @@ -7,6 +7,17 @@ Note that this setting should only be set by linkgit:git-init[1] or linkgit:git-clone[1]. Trying to change it after initialization will not work and will produce hard-to-diagnose issues. +extensions.refStorage:: + Specify the ref storage format to use. The acceptable values are: ++ +include::../ref-storage-format.txt[] ++ +It is an error to specify this key unless `core.repositoryFormatVersion` is 1. ++ +Note that this setting should only be set by linkgit:git-init[1] or +linkgit:git-clone[1]. Trying to change it after initialization will not +work and will produce hard-to-diagnose issues. + extensions.worktreeConfig:: If enabled, then worktrees will load config settings from the `$GIT_DIR/config.worktree` file in addition to the diff --git a/Documentation/config/feature.txt b/Documentation/config/feature.txt index bf9546fca4..f061b64b74 100644 --- a/Documentation/config/feature.txt +++ b/Documentation/config/feature.txt @@ -17,6 +17,9 @@ skipping more commits at a time, reducing the number of round trips. + * `pack.useBitmapBoundaryTraversal=true` may improve bitmap traversal times by walking fewer objects. ++ +* `pack.allowPackReuse=multi` may improve the time it takes to create a pack by +reusing objects from multiple packs instead of just one. feature.manyFiles:: Enable config options that optimize for repos with many files in the diff --git a/Documentation/config/fetch.txt b/Documentation/config/fetch.txt index aea5b97477..d7dc461bd1 100644 --- a/Documentation/config/fetch.txt +++ b/Documentation/config/fetch.txt @@ -50,6 +50,12 @@ fetch.pruneTags:: refs. See also `remote.<name>.pruneTags` and the PRUNING section of linkgit:git-fetch[1]. +fetch.all:: + If true, fetch will attempt to update all available remotes. + This behavior can be overridden by passing `--no-all` or by + explicitly specifying one or more remote(s) to fetch from. + Defaults to false. + fetch.output:: Control how ref update status is printed. Valid values are `full` and `compact`. Default value is `full`. See the diff --git a/Documentation/config/format.txt b/Documentation/config/format.txt index c98412b697..7410e930e5 100644 --- a/Documentation/config/format.txt +++ b/Documentation/config/format.txt @@ -119,7 +119,7 @@ format.notes:: `--notes=<ref>`, where `ref` is the non-boolean value. Defaults to false. + -If one wishes to use the ref `ref/notes/true`, please use that literal +If one wishes to use the ref `refs/notes/true`, please use that literal instead. + This configuration can be specified multiple times in order to allow diff --git a/Documentation/config/interactive.txt b/Documentation/config/interactive.txt index a2d3c7ec44..5cc26555f1 100644 --- a/Documentation/config/interactive.txt +++ b/Documentation/config/interactive.txt @@ -4,9 +4,7 @@ interactive.singleKey:: Currently this is used by the `--patch` mode of linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-restore[1], linkgit:git-commit[1], - linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this - setting is silently ignored if portable keystroke input - is not available; requires the Perl module Term::ReadKey. + linkgit:git-reset[1], and linkgit:git-stash[1]. interactive.diffFilter:: When an interactive command (such as `git add --patch`) shows diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt index 294f61efd1..00bf665aa0 100644 --- a/Documentation/config/mergetool.txt +++ b/Documentation/config/mergetool.txt @@ -45,14 +45,21 @@ 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 appear. Applies even if you are using Neovim (`nvim`) or - gVim (`gvim`) as the merge tool. See BACKEND SPECIFIC HINTS section +mergetool.<vimdiff variant>.layout:: + Configure the split window layout for vimdiff's `<variant>`, which is any of `vimdiff`, + `nvimdiff`, `gvimdiff`. + Upon launching `git mergetool` with `--tool=<variant>` (or without `--tool` + if `merge.tool` is configured as `<variant>`), Git will consult + `mergetool.<variant>.layout` to determine the tool's layout. If the + variant-specific configuration is not available, `vimdiff`'s is used as + fallback. If that too is not available, a default layout with 4 windows + will be used. To configure the layout, see the `BACKEND SPECIFIC HINTS` +ifdef::git-mergetool[] + section. +endif::[] ifndef::git-mergetool[] - in linkgit:git-mergetool[1]. + section in linkgit:git-mergetool[1]. endif::[] - for details. mergetool.hideResolved:: During a merge, Git will automatically resolve as many conflicts as diff --git a/Documentation/config/pack.txt b/Documentation/config/pack.txt index f50df9dbce..da527377fa 100644 --- a/Documentation/config/pack.txt +++ b/Documentation/config/pack.txt @@ -28,11 +28,16 @@ all existing objects. You can force recompression by passing the -F option to linkgit:git-repack[1]. pack.allowPackReuse:: - When true, and when reachability bitmaps are enabled, - pack-objects will try to send parts of the bitmapped packfile - verbatim. This can reduce memory and CPU usage to serve fetches, - but might result in sending a slightly larger pack. Defaults to - true. + When true or "single", and when reachability bitmaps are + enabled, pack-objects will try to send parts of the bitmapped + packfile verbatim. When "multi", and when a multi-pack + reachability bitmap is available, pack-objects will try to send + parts of all packs in the MIDX. ++ +If only a single pack bitmap is available, and `pack.allowPackReuse` +is set to "multi", reuse parts of just the bitmapped packfile. This +can reduce memory and CPU usage to serve fetches, but might result in +sending a slightly larger pack. Defaults to true. pack.island:: An extended regular expression configuring a set of delta diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt index d59576dbb2..c6187ab28b 100644 --- a/Documentation/config/rebase.txt +++ b/Documentation/config/rebase.txt @@ -40,7 +40,7 @@ rebase.missingCommitsCheck:: rebase.instructionFormat:: A format string, as specified in linkgit:git-log[1], to be used for the todo list during an interactive rebase. The format will - automatically have the long commit hash prepended to the format. + automatically have the commit hash prepended to the format. rebase.abbreviateCommands:: If set to true, `git rebase` will use abbreviated command names in the diff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.txt index 7fc770ee9e..6a869d67eb 100644 --- a/Documentation/config/sendemail.txt +++ b/Documentation/config/sendemail.txt @@ -8,7 +8,7 @@ sendemail.smtpEncryption:: See linkgit:git-send-email[1] for description. Note that this setting is not subject to the 'identity' mechanism. -sendemail.smtpsslcertpath:: +sendemail.smtpSSLCertPath:: Path to ca-certificates (either a directory or a single file). Set it to an empty string to disable certificate verification. @@ -62,12 +62,12 @@ sendemail.chainReplyTo:: sendemail.envelopeSender:: sendemail.from:: sendemail.headerCmd:: -sendemail.signedoffbycc:: +sendemail.signedOffByCc:: sendemail.smtpPass:: -sendemail.suppresscc:: +sendemail.suppressCc:: sendemail.suppressFrom:: sendemail.to:: -sendemail.tocmd:: +sendemail.toCmd:: sendemail.smtpDomain:: sendemail.smtpServer:: sendemail.smtpServerPort:: @@ -81,8 +81,8 @@ sendemail.xmailer:: linkgit:git-send-email[1] command-line options. See its documentation for details. -sendemail.signedoffcc (deprecated):: - Deprecated alias for `sendemail.signedoffbycc`. +sendemail.signedOffCc (deprecated):: + Deprecated alias for `sendemail.signedOffByCc`. sendemail.smtpBatchSize:: Number of messages to be sent per connection, after that a relogin diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 53ec3c9a34..aaaff0d46f 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -299,7 +299,7 @@ and accumulating child directory counts in the parent directories: Synonym for --dirstat=cumulative --dirstat-by-file[=<param1,param2>...]:: - Synonym for --dirstat=files,param1,param2... + Synonym for --dirstat=files,<param1>,<param2>... --summary:: Output a condensed summary of extended header information diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index a1d6633a4f..54ebb4452e 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -1,5 +1,6 @@ ---all:: - Fetch all remotes. +--[no-]all:: + Fetch all remotes. This overrides the configuration variable + `fetch.all`. -a:: --append:: diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index ed44c1cb31..14a371fff3 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git add' [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] - [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] [--sparse] + [--edit | -e] [--[no-]all | -A | --[no-]ignore-removal | [--update | -u]] [--sparse] [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--renormalize] [--chmod=(+|-)x] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...] @@ -63,7 +63,7 @@ OPTIONS to ignore removed files; use `--no-all` option if you want to add modified or new files but ignore removed ones. + -For more details about the <pathspec> syntax, see the 'pathspec' entry +For more details about the _<pathspec>_ syntax, see the 'pathspec' entry in linkgit:gitglossary[7]. -n:: @@ -119,10 +119,10 @@ apply to the index. See EDITING PATCHES below. -u:: --update:: Update the index just where it already has an entry matching - <pathspec>. This removes as well as modifies index entries to + _<pathspec>_. This removes as well as modifies index entries to match the working tree, but adds no new files. + -If no <pathspec> is given when `-u` option is used, all +If no _<pathspec>_ is given when `-u` option is used, all tracked files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories). @@ -131,11 +131,11 @@ subdirectories). --all:: --no-ignore-removal:: Update the index not only where the working tree has a file - matching <pathspec> but also where the index already has an + matching _<pathspec>_ but also where the index already has an entry. This adds, modifies, and removes index entries to match the working tree. + -If no <pathspec> is given when `-A` option is used, all +If no _<pathspec>_ is given when `-A` option is used, all files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories). @@ -145,11 +145,11 @@ subdirectories). Update the index by adding new files that are unknown to the index and files modified in the working tree, but ignore files that have been removed from the working tree. This - option is a no-op when no <pathspec> is used. + option is a no-op when no _<pathspec>_ is used. + This option is primarily to help users who are used to older -versions of Git, whose "git add <pathspec>..." was a synonym -for "git add --no-all <pathspec>...", i.e. ignored removed files. +versions of Git, whose "git add _<pathspec>_..." was a synonym +for "git add --no-all _<pathspec>_...", i.e. ignored removed files. -N:: --intent-to-add:: @@ -198,8 +198,8 @@ for "git add --no-all <pathspec>...", i.e. ignored removed files. unchanged. --pathspec-from-file=<file>:: - Pathspec is passed in `<file>` instead of commandline args. If - `<file>` is exactly `-` then standard input is used. Pathspec + Pathspec is passed in _<file>_ instead of commandline args. If + _<file>_ is exactly `-` then standard input is used. Pathspec elements are separated by LF or CR/LF. Pathspec elements can be quoted as explained for the configuration variable `core.quotePath` (see linkgit:git-config[1]). See also `--pathspec-file-nul` and diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index e080458d6c..463a3c6600 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -128,6 +128,9 @@ include::rerere-options.txt[] These flags are passed to the 'git apply' (see linkgit:git-apply[1]) program that applies the patch. ++ +Valid <action> for the `--whitespace` option are: +`nowarn`, `warn`, `fix`, `error`, and `error-all`. --patch-format:: By default the command will try to detect the patch format diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 191b4a42b6..82f944dc03 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -16,11 +16,11 @@ DESCRIPTION The command takes various subcommands, and different options depending on the subcommand: - git bisect start [--term-(new|bad)=<term-new> --term-(old|good)=<term-old>] - [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...] + git bisect start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>] + [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...] git bisect (bad|new|<term-new>) [<rev>] git bisect (good|old|<term-old>) [<rev>...] - git bisect terms [--term-good | --term-bad] + git bisect terms [--term-(good|old) | --term-(bad|new)] git bisect skip [(<rev>|<range>)...] git bisect reset [<commit>] git bisect (visualize|view) @@ -165,8 +165,10 @@ To get a reminder of the currently used terms, use git bisect terms ------------------------------------------------ -You can get just the old (respectively new) term with `git bisect terms ---term-old` or `git bisect terms --term-good`. +You can get just the old term with `git bisect terms --term-old` +or `git bisect terms --term-good`; `git bisect terms --term-new` +and `git bisect terms --term-bad` can be used to learn how to call +the commits more recent than the sought change. If you would like to use your own terms instead of "bad"/"good" or "new"/"old", you can choose any names you like (except existing bisect @@ -299,7 +301,7 @@ Cutting down bisection by giving more parameters to bisect start You can further cut down the number of trials, if you know what part of the tree is involved in the problem you are tracking down, by specifying -path parameters when issuing the `bisect start` command: +pathspec parameters when issuing the `bisect start` command: ------------ $ git bisect start -- arch/i386 include/asm-i386 @@ -362,7 +364,7 @@ OPTIONS --no-checkout:: + Do not checkout the new working tree at each iteration of the bisection -process. Instead just update a special reference named `BISECT_HEAD` to make +process. Instead just update the reference named `BISECT_HEAD` to make it point to the commit that should be tested. + This option may be useful when the test you would perform in each step diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index 5720d04ffe..b1d7fb539d 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -210,7 +210,7 @@ annotated. . Each blame entry always starts with a line of: - <40-byte hex sha1> <sourceline> <resultline> <num_lines> + <40-byte-hex-sha1> <sourceline> <resultline> <num-lines> + Line numbers count from 1. diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index 4395aa9354..0b08442932 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -312,7 +312,8 @@ superproject's "origin/main", but tracks the submodule's "origin/main". option is omitted, the current HEAD will be used instead. <oldbranch>:: - The name of an existing branch to rename. + The name of an existing branch. If this option is omitted, + the name of the current branch will be used instead. <newbranch>:: The new name for an existing branch. The same restrictions as for diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt index 392d9eb6ae..ca626f7fc6 100644 --- a/Documentation/git-bugreport.txt +++ b/Documentation/git-bugreport.txt @@ -52,7 +52,7 @@ OPTIONS -s <format>:: --suffix <format>:: Specify an alternate suffix for the bugreport name, to create a file - named 'git-bugreport-<formatted suffix>'. This should take the form of a + named 'git-bugreport-<formatted-suffix>'. This should take the form of a strftime(3) format string; the current local time will be used. --no-diagnose:: @@ -60,7 +60,7 @@ OPTIONS Create a zip archive of supplemental information about the user's machine, Git client, and repository state. The archive is written to the same output directory as the bug report and is named - 'git-diagnostics-<formatted suffix>'. + 'git-diagnostics-<formatted-suffix>'. + Without `mode` specified, the diagnostic archive will contain the default set of statistics reported by `git diagnose`. An optional `mode` value may be specified diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 240c54639e..8bdfa54ab0 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -63,7 +63,9 @@ $ git checkout <branch> ------------ + that is to say, the branch is not reset/created unless "git checkout" is -successful. +successful (e.g., when the branch is in use in another worktree, not +just the current branch stays the same, but the branch is not reset to +the start-point, either). 'git checkout' --detach [<branch>]:: 'git checkout' [--detach] <commit>:: @@ -215,7 +217,7 @@ variable. below for details. --orphan <new-branch>:: - Create a new 'orphan' branch, named `<new-branch>`, started from + Create a new unborn branch, named `<new-branch>`, started from `<start-point>` and switch to it. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from all the other branches and diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index c37c4a37f7..0c07720c6f 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -311,6 +311,12 @@ or `--mirror` is given) The result is Git repository can be separated from working tree. +--ref-format=<ref-format>:: + +Specify the given ref storage format for the repository. The valid values are: ++ +include::ref-storage-format.txt[] + -j <n>:: --jobs <n>:: The number of submodules fetched at the same time. diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt index c8dbceba01..903b16830e 100644 --- a/Documentation/git-commit-graph.txt +++ b/Documentation/git-commit-graph.txt @@ -13,7 +13,7 @@ SYNOPSIS 'git commit-graph write' [--object-dir <dir>] [--append] [--split[=<strategy>]] [--reachable | --stdin-packs | --stdin-commits] [--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress] - <split options> + <split-options> DESCRIPTION diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index b1caac887a..dff39093b5 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -103,11 +103,11 @@ OPTIONS names are not. --get-urlmatch <name> <URL>:: - When given a two-part name section.key, the value for - section.<URL>.key whose <URL> part matches the best to the + When given a two-part <name> as <section>.<key>, the value for + <section>.<URL>.<key> whose <URL> part matches the best to the given URL is returned (if no such key exists, the value for - section.key is used as a fallback). When given just the - section as name, do so for all the keys in the section and + <section>.<key> is used as a fallback). When given just the + <section> as name, do so for all the keys in the section and list them. Returns error code 1 if no value is found. --global:: diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt index b3f27671a0..90fdc2551a 100644 --- a/Documentation/git-cvsimport.txt +++ b/Documentation/git-cvsimport.txt @@ -22,7 +22,7 @@ DESCRIPTION deprecated; it does not work with cvsps version 3 and later. If you are performing a one-shot import of a CVS repository consider using http://cvs2svn.tigris.org/cvs2git.html[cvs2git] or -http://www.catb.org/esr/cvs-fast-export/[cvs-fast-export]. +https://gitlab.com/esr/cvs-fast-export[cvs-fast-export]. Imports a CVS repository into Git. It will either create a new repository, or incrementally import into an existing one. @@ -221,7 +221,7 @@ Problems related to tags: If you suspect that any of these issues may apply to the repository you want to import, consider using cvs2git: -* cvs2git (part of cvs2svn), `http://subversion.apache.org/` +* cvs2git (part of cvs2svn), `https://subversion.apache.org/` GIT --- diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt index cf4a5a283e..4c475efeab 100644 --- a/Documentation/git-cvsserver.txt +++ b/Documentation/git-cvsserver.txt @@ -197,7 +197,7 @@ allowing access over SSH. 5. Clients should now be able to check out the project. Use the CVS 'module' name to indicate what Git 'head' you want to check out. This also sets the name of your newly checked-out directory, unless you tell it otherwise with - `-d <dir_name>`. For example, this checks out 'master' branch to the + `-d <dir-name>`. For example, this checks out 'master' branch to the `project-master` directory: + ------ @@ -224,7 +224,7 @@ the database to work reliably (otherwise you need to make sure that the database is up to date any time 'git-cvsserver' is executed). By default it uses SQLite databases in the Git directory, named -`gitcvs.<module_name>.sqlite`. Note that the SQLite backend creates +`gitcvs.<module-name>.sqlite`. Note that the SQLite backend creates temporary files in the same directory as the database file on write so it might not be enough to grant the users using 'git-cvsserver' write access to the database file without granting diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index e064f91c9e..ede7b935d6 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -18,7 +18,7 @@ SYNOPSIS [--allow-override=<service>] [--forbid-override=<service>] [--access-hook=<path>] [--[no-]informative-errors] [--inetd | - [--listen=<host_or_ipaddr>] [--port=<n>] + [--listen=<host-or-ipaddr>] [--port=<n>] [--user=<user> [--group=<group>]]] [--log-destination=(stderr|syslog|none)] [<directory>...] @@ -86,10 +86,10 @@ OPTIONS Incompatible with --detach, --port, --listen, --user and --group options. ---listen=<host_or_ipaddr>:: +--listen=<host-or-ipaddr>:: Listen on a specific IP address or hostname. IP addresses can be either an IPv4 address or an IPv6 address if supported. If IPv6 - is not supported, then --listen=hostname is also not supported and + is not supported, then --listen=<hostname> is also not supported and --listen must be given an IPv4 address. Can be given more than once. Incompatible with `--inetd` option. @@ -141,8 +141,8 @@ otherwise `stderr`. specified with no parameter, a request to git://host/{tilde}alice/foo is taken as a request to access 'foo' repository in the home directory of user `alice`. - If `--user-path=path` is specified, the same request is - taken as a request to access `path/foo` repository in + If `--user-path=<path>` is specified, the same request is + taken as a request to access `<path>/foo` repository in the home directory of user `alice`. --verbose:: diff --git a/Documentation/git-diagnose.txt b/Documentation/git-diagnose.txt index 3ec8cc7ad7..0711959e6f 100644 --- a/Documentation/git-diagnose.txt +++ b/Documentation/git-diagnose.txt @@ -45,7 +45,7 @@ OPTIONS -s <format>:: --suffix <format>:: Specify an alternate suffix for the diagnostics archive name, to create - a file named 'git-diagnostics-<formatted suffix>'. This should take the + a file named 'git-diagnostics-<formatted-suffix>'. This should take the form of a strftime(3) format string; the current local time will be used. diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt index 08087ffad5..c065f023ec 100644 --- a/Documentation/git-diff.txt +++ b/Documentation/git-diff.txt @@ -103,7 +103,7 @@ Just in case you are doing something exotic, it should be noted that all of the <commit> in the above description, except in the `--merge-base` case and in the last two forms that use `..` notations, can be any <tree>. A tree of interest is the one pointed to -by the special ref `AUTO_MERGE`, which is written by the 'ort' merge +by the ref named `AUTO_MERGE`, which is written by the 'ort' merge strategy upon hitting merge conflicts (see linkgit:git-merge[1]). Comparing the working tree with `AUTO_MERGE` shows changes you've made so far to resolve textual conflicts (see the examples below). diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt index 50cb080085..a616f8b2e6 100644 --- a/Documentation/git-difftool.txt +++ b/Documentation/git-difftool.txt @@ -90,7 +90,7 @@ instead. `--no-symlinks` is the default on Windows. --extcmd=<command>:: Specify a custom command for viewing diffs. 'git-difftool' ignores the configured defaults and runs - `$command $LOCAL $REMOTE` when this option is specified. + `<command> $LOCAL $REMOTE` when this option is specified. Additionally, `$BASE` is set in the environment. -g:: @@ -105,7 +105,6 @@ instead. `--no-symlinks` is the default on Windows. `merge.tool` until a tool is found. --[no-]trust-exit-code:: - 'git-difftool' invokes a diff tool individually on each file. Errors reported by the diff tool are ignored by default. Use `--trust-exit-code` to make 'git-difftool' exit when an invoked diff tool returns a non-zero exit code. diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index 4643ddbe68..752e4b9b01 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -48,7 +48,7 @@ When asking to 'abort' (which is the default), this program will die when encountering such a tag. With 'drop' it will omit such tags from the output. With 'rewrite', if the tagged object is a commit, it will rewrite the tag to tag an ancestor commit (via parent rewriting; see -linkgit:git-rev-list[1]) +linkgit:git-rev-list[1]). -M:: -C:: diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index bd7b1e0a2e..b2607366b9 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -745,11 +745,11 @@ paths for a commit are encouraged to do so. `notemodify` ^^^^^^^^^^^^ -Included in a `commit` `<notes_ref>` command to add a new note +Included in a `commit` `<notes-ref>` command to add a new note annotating a `<commit-ish>` or change this annotation contents. Internally it is similar to filemodify 100644 on `<commit-ish>` path (maybe split into subdirectories). It's not advised to -use any other commands to write to the `<notes_ref>` tree except +use any other commands to write to the `<notes-ref>` tree except `filedeleteall` to delete all existing notes in this tree. This command has two different means of specifying the content of the note. diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt index f123139c58..50900a50da 100644 --- a/Documentation/git-fetch.txt +++ b/Documentation/git-fetch.txt @@ -186,8 +186,8 @@ origin: ------------------------------------------------ $ git fetch origin --prune --prune-tags $ git fetch origin --prune 'refs/tags/*:refs/tags/*' -$ git fetch <url of origin> --prune --prune-tags -$ git fetch <url of origin> --prune 'refs/tags/*:refs/tags/*' +$ git fetch <url-of-origin> --prune --prune-tags +$ git fetch <url-of-origin> --prune 'refs/tags/*:refs/tags/*' ------------------------------------------------ OUTPUT diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 62e482a95e..5a4f853785 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -14,7 +14,7 @@ SYNOPSIS [--msg-filter <command>] [--commit-filter <command>] [--tag-name-filter <command>] [--prune-empty] [--original <namespace>] [-d <directory>] [-f | --force] - [--state-branch <branch>] [--] [<rev-list options>...] + [--state-branch <branch>] [--] [<rev-list-options>...] WARNING ------- @@ -32,7 +32,7 @@ listed there as reasonably possible. DESCRIPTION ----------- Lets you rewrite Git revision history by rewriting the branches mentioned -in the <rev-list options>, applying custom filters on each revision. +in the <rev-list-options>, applying custom filters on each revision. Those filters can modify each tree (e.g. removing a file or running a perl rewrite on all files) or information about each commit. Otherwise, all information (including original commit times or merge @@ -624,7 +624,7 @@ with: real backup; it dereferences tags first.) ** Running git-filter-branch with either --tags or --all in your - <rev-list options>. In order to retain annotated tags as + <rev-list-options>. In order to retain annotated tags as annotated, you must use --tag-name-filter (and must not have restored from refs/original/ in a previously botched rewrite). diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index e86d5700dd..c1dd12b93c 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl] [(--sort=<key>)...] [--format=<format>] - [ --stdin | <pattern>... ] + [--include-root-refs] [ --stdin | <pattern>... ] [--points-at=<object>] [--merged[=<object>]] [--no-merged[=<object>]] [--contains[=<object>]] [--no-contains[=<object>]] @@ -51,17 +51,14 @@ OPTIONS key. --format=<format>:: - A string that interpolates `%(fieldname)` from a ref being shown - and the object it points at. If `fieldname` - is prefixed with an asterisk (`*`) and the ref points - at a tag object, use the value for the field in the object - which the tag object refers to (instead of the field in the tag object). - When unspecified, `<format>` defaults to - `%(objectname) SPC %(objecttype) TAB %(refname)`. - It also interpolates `%%` to `%`, and `%xx` where `xx` - are hex digits interpolates to character with hex code - `xx`; for example `%00` interpolates to `\0` (NUL), - `%09` to `\t` (TAB) and `%0a` to `\n` (LF). + A string that interpolates `%(fieldname)` from a ref being shown and + the object it points at. In addition, the string literal `%%` + renders as `%` and `%xx` - where `xx` are hex digits - renders as + the character with hex code `xx`. For example, `%00` interpolates to + `\0` (NUL), `%09` to `\t` (TAB), and `%0a` to `\n` (LF). ++ +When unspecified, `<format>` defaults to `%(objectname) SPC %(objecttype) +TAB %(refname)`. --color[=<when>]:: Respect any colors specified in the `--format` option. The @@ -108,6 +105,9 @@ OPTIONS any excluded pattern(s) are shown. Matching is done using the same rules as `<pattern>` above. +--include-root-refs:: + List root refs (HEAD and pseudorefs) apart from regular refs. + FIELD NAMES ----------- @@ -298,6 +298,10 @@ fields will correspond to the appropriate date or name-email-date tuple from the `committer` or `tagger` fields depending on the object type. These are intended for working on a mix of annotated and lightweight tags. +For tag objects, a `fieldname` prefixed with an asterisk (`*`) expands to +the `fieldname` value of the peeled object, rather than that of the tag +object itself. + Fields that have name-email-date tuple as its value (`author`, `committer`, and `tagger`) can be suffixed with `name`, `email`, and `date` to extract the named component. For email fields (`authoremail`, @@ -358,9 +362,11 @@ In any case, a field name that refers to a field inapplicable to the object referred by the ref does not cause an error. It returns an empty string instead. -As a special case for the date-type fields, you may specify a format for -the date by adding `:` followed by date format name (see the -values the `--date` option to linkgit:git-rev-list[1] takes). +As a special case for the date-type fields, you may specify a format for the +date by adding `:` followed by date format name (see the values the `--date` +option to linkgit:git-rev-list[1] takes). If this formatting is provided in +a `--sort` key, references will be sorted according to the byte-value of the +formatted string rather than the numeric value of the underlying timestamp. Some atoms like %(align) and %(if) always require a matching %(end). We call them "opening atoms" and sometimes denote them as %($open). diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index aaafce24be..728bb3821c 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -17,10 +17,10 @@ SYNOPSIS [--signature-file=<file>] [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] - [--in-reply-to=<message id>] [--suffix=.<sfx>] + [--in-reply-to=<message-id>] [--suffix=.<sfx>] [--ignore-if-in-upstream] [--always] [--cover-from-description=<mode>] - [--rfc] [--subject-prefix=<subject prefix>] + [--rfc] [--subject-prefix=<subject-prefix>] [(--reroll-count|-v) <n>] [--to=<email>] [--cc=<email>] [--[no-]cover-letter] [--quiet] @@ -30,8 +30,8 @@ SYNOPSIS [--range-diff=<previous> [--creation-factor=<percent>]] [--filename-max-length=<n>] [--progress] - [<common diff options>] - [ <since> | <revision range> ] + [<common-diff-options>] + [ <since> | <revision-range> ] DESCRIPTION ----------- @@ -64,7 +64,7 @@ There are two ways to specify which commits to operate on. to the tip of the current branch that are not in the history that leads to the <since> to be output. -2. Generic <revision range> expression (see "SPECIFYING +2. Generic <revision-range> expression (see "SPECIFYING REVISIONS" section in linkgit:gitrevisions[7]) means the commits in the specified range. @@ -179,9 +179,9 @@ Beware that the default for 'git send-email' is to thread emails itself. If you want `git format-patch` to take care of threading, you will want to ensure that threading is disabled for `git send-email`. ---in-reply-to=<message id>:: +--in-reply-to=<message-id>:: Make the first mail (or all the mails with `--no-thread`) appear as a - reply to the given <message id>, which avoids breaking threads to + reply to the given <message-id>, which avoids breaking threads to provide a new patch series. --ignore-if-in-upstream:: @@ -219,9 +219,9 @@ populated with placeholder text. Use the contents of <file> instead of the branch's description for generating the cover letter. ---subject-prefix=<subject prefix>:: +--subject-prefix=<subject-prefix>:: Instead of the standard '[PATCH]' prefix in the subject - line, instead use '[<subject prefix>]'. This can be used + line, instead use '[<subject-prefix>]'. This can be used to name a patch series, and can be combined with the `--numbered` option. + @@ -403,7 +403,7 @@ you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. `format.useAutoBase` configuration. --root:: - Treat the revision argument as a <revision range>, even if it + Treat the revision argument as a <revision-range>, even if it is just a single commit (that would normally be treated as a <since>). Note that root commits included in the specified range are always formatted as creation patches, independently @@ -610,8 +610,8 @@ Approach #3 (external editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following Thunderbird extensions are needed: -AboutConfig from http://aboutconfig.mozdev.org/ and -External Editor from http://globs.org/articles.php?lng=en&pg=8 +AboutConfig from https://mjg.github.io/AboutConfig/ and +External Editor from https://globs.org/articles.php?lng=en&pg=8 1. Prepare the patch as a text file using your method of choice. diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt index f7b1851514..c8a89d7243 100644 --- a/Documentation/git-imap-send.txt +++ b/Documentation/git-imap-send.txt @@ -135,7 +135,7 @@ flames ridiculing you if you don't check this. Thunderbird in particular is known to be problematic. Thunderbird users may wish to visit this web page for more information: - http://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email + https://kb.mozillazine.org/Plain_text_e-mail_-_Thunderbird#Completely_plain_email SEE ALSO -------- diff --git a/Documentation/git-index-pack.txt b/Documentation/git-index-pack.txt index 6486620c3d..5a20deefd5 100644 --- a/Documentation/git-index-pack.txt +++ b/Documentation/git-index-pack.txt @@ -79,8 +79,13 @@ OPTIONS to force the version for the generated pack index, and to force 64-bit index entries on objects located above the given offset. ---strict:: - Die, if the pack contains broken objects or links. +--strict[=<msg-id>=<severity>...]:: + Die, if the pack contains broken objects or links. An optional + comma-separated list of `<msg-id>=<severity>` can be passed to change + the severity of some possible issues, e.g., + `--strict="missingEmail=ignore,badTagName=error"`. See the entry for the + `fsck.<msg-id>` configuration options in linkgit:git-fsck[1] for more + information on the possible values of `<msg-id>` and `<severity>`. --progress-title:: For internal use only. @@ -91,13 +96,18 @@ default and "Indexing objects" when `--stdin` is specified. --check-self-contained-and-connected:: Die if the pack contains broken links. For internal use only. ---fsck-objects:: - For internal use only. +--fsck-objects[=<msg-id>=<severity>...]:: + Die if the pack contains broken objects, but unlike `--strict`, don't + choke on broken links. If the pack contains a tree pointing to a + .gitmodules blob that does not exist, prints the hash of that blob + (for the caller to check) after the hash that goes into the name of the + pack/idx file (see "Notes"). + -Die if the pack contains broken objects. If the pack contains a tree -pointing to a .gitmodules blob that does not exist, prints the hash of -that blob (for the caller to check) after the hash that goes into the -name of the pack/idx file (see "Notes"). +An optional comma-separated list of `<msg-id>=<severity>` can be passed to +change the severity of some possible issues, e.g., +`--fsck-objects="missingEmail=ignore,badTagName=ignore"`. See the entry for the +`fsck.<msg-id>` configuration options in linkgit:git-fsck[1] for more +information on the possible values of `<msg-id>` and `<severity>`. --threads=<n>:: Specifies the number of threads to spawn when resolving diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 6f0d2973bf..e8dc645bb5 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -11,6 +11,7 @@ SYNOPSIS [verse] 'git init' [-q | --quiet] [--bare] [--template=<template-directory>] [--separate-git-dir <git-dir>] [--object-format=<format>] + [--ref-format=<format>] [-b <branch-name> | --initial-branch=<branch-name>] [--shared[=<permissions>]] [<directory>] @@ -57,6 +58,12 @@ values are 'sha1' and (if enabled) 'sha256'. 'sha1' is the default. + include::object-format-disclaimer.txt[] +--ref-format=<format>:: + +Specify the given ref storage format for the repository. The valid values are: ++ +include::ref-storage-format.txt[] + --template=<template-directory>:: Specify the directory from which templates will be used. (See the "TEMPLATE diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt index f65a8cd91d..d08c7da8f4 100644 --- a/Documentation/git-ls-files.txt +++ b/Documentation/git-ls-files.txt @@ -119,8 +119,10 @@ OPTIONS --exclude-per-directory=<file>:: Read additional exclude patterns that apply only to the - directory and its subdirectories in <file>. Deprecated; use - --exclude-standard instead. + directory and its subdirectories in <file>. If you are + trying to emulate the way Porcelain commands work, using + the `--exclude-standard` option instead is easier and more + thorough. --exclude-standard:: Add the standard Git exclusions: .git/info/exclude, .gitignore @@ -298,9 +300,8 @@ traversing the directory tree and finding files to show when the flags --others or --ignored are specified. linkgit:gitignore[5] specifies the format of exclude patterns. -Generally, you should just use --exclude-standard, but for historical -reasons the exclude patterns can be specified from the following -places, in order: +These exclude patterns can be specified from the following places, +in order: 1. The command-line flag --exclude=<pattern> specifies a single pattern. Patterns are ordered in the same order @@ -322,6 +323,18 @@ top of the directory tree. A pattern read from a file specified by --exclude-per-directory is relative to the directory that the pattern file appears in. +Generally, you should be able to use `--exclude-standard` when you +want the exclude rules applied the same way as what Porcelain +commands do. To emulate what `--exclude-standard` specifies, you +can give `--exclude-per-directory=.gitignore`, and then specify: + + 1. The file specified by the `core.excludesfile` configuration + variable, if exists, or the `$XDG_CONFIG_HOME/git/ignore` file. + + 2. The `$GIT_DIR/info/exclude` file. + +via the `--exclude-from=` option. + SEE ALSO -------- linkgit:git-read-tree[1], linkgit:gitignore[5] diff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.txt index 6a081eacb7..71915a00fa 100644 --- a/Documentation/git-merge-file.txt +++ b/Documentation/git-merge-file.txt @@ -92,6 +92,12 @@ object store and the object ID of its blob is written to standard output. Instead of leaving conflicts in the file, resolve conflicts favouring our (or their or both) side of the lines. +--diff-algorithm={patience|minimal|histogram|myers}:: + Use a different diff algorithm while merging. The current default is "myers", + but selecting more recent algorithm such as "histogram" can help + avoid mismerges that occur due to unimportant matching lines + (such as braces from distinct functions). See also + linkgit:git-diff[1] `--diff-algorithm`. EXAMPLES -------- diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index e8ab340319..1ab69f61f5 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -20,12 +20,12 @@ DESCRIPTION ----------- Incorporates changes from the named commits (since the time their histories diverged from the current branch) into the current -branch. This command is used by 'git pull' to incorporate changes +branch. This command is used by `git pull` to incorporate changes from another repository and can be used by hand to merge changes from one branch into another. Assume the following history exists and the current branch is -"`master`": +`master`: ------------ A---B---C topic @@ -33,7 +33,7 @@ Assume the following history exists and the current branch is D---E---F---G master ------------ -Then "`git merge topic`" will replay the changes made on the +Then `git merge topic` will replay the changes made on the `topic` branch since it diverged from `master` (i.e., `E`) until its current commit (`C`) on top of `master`, and record the result in a new commit along with the names of the two parent commits and @@ -46,21 +46,21 @@ a log message from the user describing the changes. Before the operation, D---E---F---G---H master ------------ -The second syntax ("`git merge --abort`") can only be run after the -merge has resulted in conflicts. 'git merge --abort' will abort the -merge process and try to reconstruct the pre-merge state. However, -if there were uncommitted changes when the merge started (and -especially if those changes were further modified after the merge -was started), 'git merge --abort' will in some cases be unable to -reconstruct the original (pre-merge) changes. Therefore: +A merge stops if there's a conflict that cannot be resolved +automatically or if `--no-commit` was provided when initiating the +merge. At that point you can run `git merge --abort` or `git merge +--continue`. -*Warning*: Running 'git merge' with non-trivial uncommitted changes is +`git merge --abort` will abort the merge process and try to reconstruct +the pre-merge state. However, if there were uncommitted changes when the +merge started (and especially if those changes were further modified +after the merge was started), `git merge --abort` will in some cases be +unable to reconstruct the original (pre-merge) changes. Therefore: + +*Warning*: Running `git merge` with non-trivial uncommitted changes is discouraged: while possible, it may leave you in a state that is hard to back out of in the case of a conflict. -The third syntax ("`git merge --continue`") can only be run after the -merge has resulted in conflicts. - OPTIONS ------- :git-merge: 1 @@ -74,8 +74,8 @@ include::merge-options.txt[] If `--log` is specified, a shortlog of the commits being merged will be appended to the specified message. + -The 'git fmt-merge-msg' command can be -used to give a good default for automated 'git merge' +The `git fmt-merge-msg` command can be +used to give a good default for automated `git merge` invocations. The automated message can include the branch description. --into-name <branch>:: @@ -104,14 +104,14 @@ include::rerere-options.txt[] present, apply it to the worktree. + If there were uncommitted worktree changes present when the merge -started, 'git merge --abort' will in some cases be unable to +started, `git merge --abort` will in some cases be unable to reconstruct these changes. It is therefore recommended to always -commit or stash your changes before running 'git merge'. +commit or stash your changes before running `git merge`. + -'git merge --abort' is equivalent to 'git reset --merge' when +`git merge --abort` is equivalent to `git reset --merge` when `MERGE_HEAD` is present unless `MERGE_AUTOSTASH` is also present in -which case 'git merge --abort' applies the stash entry to the worktree -whereas 'git reset --merge' will save the stashed changes in the stash +which case `git merge --abort` applies the stash entry to the worktree +whereas `git reset --merge` will save the stashed changes in the stash list. --quit:: @@ -120,8 +120,8 @@ list. stash entry will be saved to the stash list. --continue:: - After a 'git merge' stops due to conflicts you can conclude the - merge by running 'git merge --continue' (see "HOW TO RESOLVE + After a `git merge` stops due to conflicts you can conclude the + merge by running `git merge --continue` (see "HOW TO RESOLVE CONFLICTS" section below). <commit>...:: @@ -144,25 +144,25 @@ PRE-MERGE CHECKS Before applying outside changes, you should get your own work in good shape and committed locally, so it will not be clobbered if there are conflicts. See also linkgit:git-stash[1]. -'git pull' and 'git merge' will stop without doing anything when -local uncommitted changes overlap with files that 'git pull'/'git -merge' may need to update. +`git pull` and `git merge` will stop without doing anything when +local uncommitted changes overlap with files that `git pull`/`git +merge` may need to update. To avoid recording unrelated changes in the merge commit, -'git pull' and 'git merge' will also abort if there are any changes +`git pull` and `git merge` will also abort if there are any changes registered in the index relative to the `HEAD` commit. (Special narrow exceptions to this rule may exist depending on which merge strategy is in use, but generally, the index must match HEAD.) -If all named commits are already ancestors of `HEAD`, 'git merge' +If all named commits are already ancestors of `HEAD`, `git merge` will exit early with the message "Already up to date." FAST-FORWARD MERGE ------------------ Often the current branch head is an ancestor of the named commit. -This is the most common case especially when invoked from 'git -pull': you are tracking an upstream repository, you have committed +This is the most common case especially when invoked from `git +pull`: you are tracking an upstream repository, you have committed no local changes, and now you want to update to a newer upstream revision. In this case, a new commit is not needed to store the combined history; instead, the `HEAD` (along with the index) is @@ -196,7 +196,7 @@ happens: can inspect the stages with `git ls-files -u`). The working tree files contain the result of the merge operation; i.e. 3-way merge results with familiar conflict markers `<<<` `===` `>>>`. -5. A special ref `AUTO_MERGE` is written, pointing to a tree +5. A ref named `AUTO_MERGE` is written, pointing to a tree corresponding to the current content of the working tree (including conflict markers for textual conflicts). Note that this ref is only written when the 'ort' merge strategy is used (the default). @@ -269,7 +269,7 @@ Barbie's remark on your side. The only thing you can tell is that your side wants to say it is hard and you'd prefer to go shopping, while the other side wants to claim it is easy. -An alternative style can be used by setting the "merge.conflictStyle" +An alternative style can be used by setting the `merge.conflictStyle` configuration variable to either "diff3" or "zdiff3". In "diff3" style, the above conflict may look like this: @@ -328,10 +328,10 @@ After seeing a conflict, you can do two things: * Resolve the conflicts. Git will mark the conflicts in the working tree. Edit the files into shape and - 'git add' them to the index. Use 'git commit' or - 'git merge --continue' to seal the deal. The latter command + `git add` them to the index. Use `git commit` or + `git merge --continue` to seal the deal. The latter command checks whether there is a (interrupted) merge in progress - before calling 'git commit'. + before calling `git commit`. You can work through the conflict with a number of tools: @@ -392,7 +392,7 @@ CONFIGURATION branch.<name>.mergeOptions:: Sets default options for merging into branch <name>. The syntax and - supported options are the same as those of 'git merge', but option + supported options are the same as those of `git merge`, but option values containing whitespace characters are currently not supported. include::includes/cmd-config-section-rest.txt[] diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt index 7f991a3380..dc1bf61534 100644 --- a/Documentation/git-mv.txt +++ b/Documentation/git-mv.txt @@ -16,7 +16,7 @@ DESCRIPTION Move or rename a file, directory, or symlink. git mv [-v] [-f] [-n] [-k] <source> <destination> - git mv [-v] [-f] [-n] [-k] <source> ... <destination directory> + git mv [-v] [-f] [-n] [-k] <source> ... <destination-directory> In the first form, it renames <source>, which must exist and be either a file, symlink or directory, to <destination>. diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index f8310e56a8..c9221a68cc 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -56,7 +56,7 @@ SUBCOMMANDS list:: List the notes object for a given object. If no object is given, show a list of all note objects and the objects they - annotate (in the format "<note object> <annotated object>"). + annotate (in the format "<note-object> <annotated-object>"). This is the default subcommand if no subcommand is given. add:: diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index ba96fb5714..e7e725044d 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -523,7 +523,7 @@ See also INCOMPATIBLE OPTIONS below. + The commit list format can be changed by setting the configuration option rebase.instructionFormat. A customized instruction format will automatically -have the long commit hash prepended to the format. +have the commit hash prepended to the format. + See also INCOMPATIBLE OPTIONS below. @@ -626,13 +626,16 @@ See also INCOMPATIBLE OPTIONS below. Automatically reschedule `exec` commands that failed. This only makes sense in interactive mode (or when an `--exec` option was provided). + -Even though this option applies once a rebase is started, it's set for -the whole rebase at the start based on either the -`rebase.rescheduleFailedExec` configuration (see linkgit:git-config[1] -or "CONFIGURATION" below) or whether this option is -provided. Otherwise an explicit `--no-reschedule-failed-exec` at the -start would be overridden by the presence of -`rebase.rescheduleFailedExec=true` configuration. +This option applies once a rebase is started. It is preserved for the whole +rebase based on, in order, the command line option provided to the initial `git +rebase`, the `rebase.rescheduleFailedExec` configuration (see +linkgit:git-config[1] or "CONFIGURATION" below), or it defaults to false. ++ +Recording this option for the whole rebase is a convenience feature. Otherwise +an explicit `--no-reschedule-failed-exec` at the start would be overridden by +the presence of a `rebase.rescheduleFailedExec=true` configuration when `git +rebase --continue` is invoked. Currently, you cannot pass +`--[no-]reschedule-failed-exec` to `git rebase --continue`. --update-refs:: --no-update-refs:: @@ -963,10 +966,9 @@ The interactive rebase will stop when a command fails (i.e. exits with non-0 status) to give you an opportunity to fix the problem. You can continue with `git rebase --continue`. -The "exec" command launches the command in a shell (the one specified -in `$SHELL`, or the default shell if `$SHELL` is not set), so you can -use shell features (like "cd", ">", ";" ...). The command is run from -the root of the working tree. +The "exec" command launches the command in a shell (the default one, usually +/bin/sh), so you can use shell features (like "cd", ">", ";" ...). The command +is run from the root of the working tree. ---------------------------------- $ git rebase -i --exec "make test" diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index ec64cbff4c..a929c52982 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -10,6 +10,7 @@ SYNOPSIS -------- [verse] 'git reflog' [show] [<log-options>] [<ref>] +'git reflog list' 'git reflog expire' [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...] @@ -39,6 +40,8 @@ actions, and in addition the `HEAD` reflog records branch switching. `git reflog show` is an alias for `git log -g --abbrev-commit --pretty=oneline`; see linkgit:git-log[1] for more information. +The "list" subcommand lists all refs which have a corresponding reflog. + The "expire" subcommand prunes older reflog entries. Entries older than `expire` time, or entries older than `expire-unreachable` time and not reachable from the current tip, are removed from the reflog. diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index 1dec314834..932a5c3ea4 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -35,7 +35,7 @@ OPTIONS -v:: --verbose:: Be a little more verbose and show remote url after name. - For promisor remotes, also show which filter (`blob:none` etc.) + For promisor remotes, also show which filters (`blob:none` etc.) are configured. NOTE: This must be placed between `remote` and subcommand. diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt index 4f257126e3..0a65460adb 100644 --- a/Documentation/git-replace.txt +++ b/Documentation/git-replace.txt @@ -114,11 +114,11 @@ FORMATS The following formats are available: * 'short': - <replaced sha1> + <replaced-sha1> * 'medium': - <replaced sha1> -> <replacement sha1> + <replaced-sha1> -> <replacement-sha1> * 'long': - <replaced sha1> (<replaced type>) -> <replacement sha1> (<replacement type>) + <replaced-sha1> (<replaced-type>) -> <replacement-sha1> (<replacement-type>) CREATING REPLACEMENT OBJECTS ---------------------------- diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.txt new file mode 100644 index 0000000000..f6c269c62d --- /dev/null +++ b/Documentation/git-replay.txt @@ -0,0 +1,127 @@ +git-replay(1) +============= + +NAME +---- +git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos too + + +SYNOPSIS +-------- +[verse] +(EXPERIMENTAL!) 'git replay' ([--contained] --onto <newbase> | --advance <branch>) <revision-range>... + +DESCRIPTION +----------- + +Takes ranges of commits and replays them onto a new location. Leaves +the working tree and the index untouched, and updates no references. +The output of this command is meant to be used as input to +`git update-ref --stdin`, which would update the relevant branches +(see the OUTPUT section below). + +THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. + +OPTIONS +------- + +--onto <newbase>:: + Starting point at which to create the new commits. May be any + valid commit, and not just an existing branch name. ++ +When `--onto` is specified, the update-ref command(s) in the output will +update the branch(es) in the revision range to point at the new +commits, similar to the way how `git rebase --update-refs` updates +multiple branches in the affected range. + +--advance <branch>:: + Starting point at which to create the new commits; must be a + branch name. ++ +When `--advance` is specified, the update-ref command(s) in the output +will update the branch passed as an argument to `--advance` to point at +the new commits (in other words, this mimics a cherry-pick operation). + +<revision-range>:: + Range of commits to replay. More than one <revision-range> can + be passed, but in `--advance <branch>` mode, they should have + a single tip, so that it's clear where <branch> should point + to. See "Specifying Ranges" in linkgit:git-rev-parse and the + "Commit Limiting" options below. + +include::rev-list-options.txt[] + +OUTPUT +------ + +When there are no conflicts, the output of this command is usable as +input to `git update-ref --stdin`. It is of the form: + + update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} + update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} + update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH} + +where the number of refs updated depends on the arguments passed and +the shape of the history being replayed. When using `--advance`, the +number of refs updated is always one, but for `--onto`, it can be one +or more (rebasing multiple branches simultaneously is supported). + +EXIT STATUS +----------- + +For a successful, non-conflicted replay, the exit status is 0. When +the replay has conflicts, the exit status is 1. If the replay is not +able to complete (or start) due to some kind of error, the exit status +is something other than 0 or 1. + +EXAMPLES +-------- + +To simply rebase `mybranch` onto `target`: + +------------ +$ git replay --onto target origin/main..mybranch +update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH} +------------ + +To cherry-pick the commits from mybranch onto target: + +------------ +$ git replay --advance target origin/main..mybranch +update refs/heads/target ${NEW_target_HASH} ${OLD_target_HASH} +------------ + +Note that the first two examples replay the exact same commits and on +top of the exact same new base, they only differ in that the first +provides instructions to make mybranch point at the new commits and +the second provides instructions to make target point at them. + +What if you have a stack of branches, one depending upon another, and +you'd really like to rebase the whole set? + +------------ +$ git replay --contained --onto origin/main origin/main..tipbranch +update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} +update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} +update refs/heads/tipbranch ${NEW_tipbranch_HASH} ${OLD_tipbranch_HASH} +------------ + +When calling `git replay`, one does not need to specify a range of +commits to replay using the syntax `A..B`; any range expression will +do: + +------------ +$ git replay --onto origin/main ^base branch1 branch2 branch3 +update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} +update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} +update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH} +------------ + +This will simultaneously rebase `branch1`, `branch2`, and `branch3`, +all commits they have since `base`, playing them on top of +`origin/main`. These three branches may have commits on top of `base` +that they have in common, but that does not need to be the case. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 912fab9f5e..5d83dd36da 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -9,7 +9,7 @@ git-rev-parse - Pick out and massage parameters SYNOPSIS -------- [verse] -'git rev-parse' [<options>] <args>... +'git rev-parse' [<options>] <arg>... DESCRIPTION ----------- @@ -130,7 +130,7 @@ for another option. 'git diff-{asterisk}'). In contrast to the `--sq-quote` option, the command input is still interpreted as usual. ---short[=length]:: +--short[=<length>]:: Same as `--verify` but shortens the object name to a unique prefix with at least `length` characters. The minimum length is 4, the default is the effective value of the `core.abbrev` @@ -165,9 +165,9 @@ Options for Objects --all:: Show all refs found in `refs/`. ---branches[=pattern]:: ---tags[=pattern]:: ---remotes[=pattern]:: +--branches[=<pattern>]:: +--tags[=<pattern>]:: +--remotes[=<pattern>]:: Show all branches, tags, or remote-tracking branches, respectively (i.e., refs found in `refs/heads`, `refs/tags`, or `refs/remotes`, respectively). @@ -176,7 +176,7 @@ If a `pattern` is given, only refs matching the given shell glob are shown. If the pattern does not contain a globbing character (`?`, `*`, or `[`), it is turned into a prefix match by appending `/*`. ---glob=pattern:: +--glob=<pattern>:: Show all refs matching the shell glob pattern `pattern`. If the pattern does not start with `refs/`, this is automatically prepended. If the pattern does not contain a globbing @@ -197,7 +197,7 @@ respectively, and they must begin with `refs/` when applied to `--glob` or `--all`. If a trailing '/{asterisk}' is intended, it must be given explicitly. ---exclude-hidden=[fetch|receive|uploadpack]:: +--exclude-hidden=(fetch|receive|uploadpack):: Do not include refs that would be hidden by `git-fetch`, `git-receive-pack` or `git-upload-pack` by consulting the appropriate `fetch.hideRefs`, `receive.hideRefs` or `uploadpack.hideRefs` @@ -307,21 +307,24 @@ The following options are unaffected by `--path-format`: input, multiple algorithms may be printed, space-separated. If not specified, the default is "storage". +--show-ref-format:: + Show the reference storage format used for the repository. + Other Options ~~~~~~~~~~~~~ ---since=datestring:: ---after=datestring:: +--since=<datestring>:: +--after=<datestring>:: Parse the date string, and output the corresponding --max-age= parameter for 'git rev-list'. ---until=datestring:: ---before=datestring:: +--until=<datestring>:: +--before=<datestring>:: Parse the date string, and output the corresponding --min-age= parameter for 'git rev-list'. -<args>...:: +<arg>...:: Flags and parameters to be parsed. diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt index cbe0208834..568925db53 100644 --- a/Documentation/git-revert.txt +++ b/Documentation/git-revert.txt @@ -116,7 +116,7 @@ include::rerere-options.txt[] --reference:: Instead of starting the body of the log message with "This - reverts <full object name of the commit being reverted>.", + reverts <full-object-name-of-the-commit-being-reverted>.", refer to the commit using "--pretty=reference" format (cf. linkgit:git-log[1]). The `revert.reference` configuration variable can be used to enable this option by @@ -149,7 +149,7 @@ While git creates a basic commit message automatically, it is _strongly_ recommended to explain why the original commit is being reverted. In addition, repeatedly reverting reverts will result in increasingly -unwieldy subject lines, for example 'Reapply "Reapply "<original subject>""'. +unwieldy subject lines, for example 'Reapply "Reapply "<original-subject>""'. Please consider rewording these to be shorter and more unique. CONFIGURATION diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 465011bad5..8264f87380 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git send-email' [<options>] <file|directory>... -'git send-email' [<options>] <format-patch options> +'git send-email' [<options>] <format-patch-options> 'git send-email' --dump-aliases @@ -138,7 +138,7 @@ Note that no attempts whatsoever are made to validate the encoding. --compose-encoding=<encoding>:: Specify encoding of compose message. Default is the value of the - 'sendemail.composeencoding'; if that is unspecified, UTF-8 is assumed. + 'sendemail.composeEncoding'; if that is unspecified, UTF-8 is assumed. --transfer-encoding=(7bit|8bit|quoted-printable|base64|auto):: Specify the transfer encoding to be used to send the message over SMTP. @@ -174,7 +174,7 @@ Sending Specify a command to run to send the email. The command should be sendmail-like; specifically, it must support the `-i` option. The command will be executed in the shell if necessary. Default - is the value of `sendemail.sendmailcmd`. If unspecified, and if + is the value of `sendemail.sendmailCmd`. If unspecified, and if --smtp-server is also unspecified, git-send-email will search for `sendmail` in `/usr/sbin`, `/usr/lib` and $PATH. @@ -269,7 +269,7 @@ must be used for each option. certificates concatenated together: see verify(1) -CAfile and -CApath for more information on these). Set it to an empty string to disable certificate verification. Defaults to the value of the - `sendemail.smtpsslcertpath` configuration variable, if set, or the + `sendemail.smtpSSLCertPath` configuration variable, if set, or the backing SSL library's compiled-in default otherwise (which should be the best choice on most platforms). @@ -313,7 +313,7 @@ Automating Specify a command to execute once per patch file which should generate patch file specific "To:" entries. Output of this command must be single email address per line. - Default is the value of 'sendemail.tocmd' configuration value. + Default is the value of 'sendemail.toCmd' configuration value. --cc-cmd=<command>:: Specify a command to execute once per patch file which @@ -348,19 +348,19 @@ Automating --[no-]signed-off-by-cc:: If this is set, add emails found in the `Signed-off-by` trailer or Cc: lines to the - cc list. Default is the value of `sendemail.signedoffbycc` configuration + cc list. Default is the value of `sendemail.signedOffByCc` configuration value; if that is unspecified, default to --signed-off-by-cc. --[no-]cc-cover:: If this is set, emails found in Cc: headers in the first patch of the series (typically the cover letter) are added to the cc list - for each email set. Default is the value of 'sendemail.cccover' + for each email set. Default is the value of 'sendemail.ccCover' configuration value; if that is unspecified, default to --no-cc-cover. --[no-]to-cover:: If this is set, emails found in To: headers in the first patch of the series (typically the cover letter) are added to the to list - for each email set. Default is the value of 'sendemail.tocover' + for each email set. Default is the value of 'sendemail.toCover' configuration value; if that is unspecified, default to --no-to-cover. --suppress-cc=<category>:: @@ -384,7 +384,7 @@ Automating - 'all' will suppress all auto cc values. -- + -Default is the value of `sendemail.suppresscc` configuration value; if +Default is the value of `sendemail.suppressCc` configuration value; if that is unspecified, default to 'self' if --suppress-from is specified, as well as 'body' if --no-signed-off-cc is specified. @@ -454,7 +454,7 @@ have been specified, in which case default to 'compose'. 998 characters unless a suitable transfer encoding ('auto', 'base64', or 'quoted-printable') is used; this is due to SMTP limits as described by - http://www.ietf.org/rfc/rfc5322.txt. + https://www.ietf.org/rfc/rfc5322.txt. -- + Default is the value of `sendemail.validate`; if this is not set, @@ -471,7 +471,7 @@ Information Instead of the normal operation, dump the shorthand alias names from the configured alias file(s), one per line in alphabetical order. Note that this only includes the alias name and not its expanded email addresses. - See 'sendemail.aliasesfile' for more information about aliases. + See 'sendemail.aliasesFile' for more information about aliases. CONFIGURATION diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index 10fecc51a7..4dbb88373b 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -309,7 +309,7 @@ Line Notes ------------------------------------------------------------ # branch.oid <commit> | (initial) Current commit. # branch.head <branch> | (detached) Current branch. -# branch.upstream <upstream_branch> If upstream is set. +# branch.upstream <upstream-branch> If upstream is set. # branch.ab +<ahead> -<behind> If upstream is set and the commit is present. ------------------------------------------------------------ @@ -502,7 +502,7 @@ results, so it could be faster on subsequent runs. usually worth the additional size. * `core.untrackedCache=true` and `core.fsmonitor=true` or - `core.fsmonitor=<hook_command_pathname>` (see + `core.fsmonitor=<hook-command-pathname>` (see linkgit:git-update-index[1]): enable both the untracked cache and FSMonitor features and only search directories that have been modified since the previous `git status` command. This diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 695730609a..ca0347a37b 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -136,7 +136,7 @@ If you really want to remove a submodule from the repository and commit that use linkgit:git-rm[1] instead. See linkgit:gitsubmodules[7] for removal options. -update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--filter <filter spec>] [--] [<path>...]:: +update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--filter <filter-spec>] [--] [<path>...]:: + -- Update the registered submodules to match what the superproject @@ -185,7 +185,7 @@ submodule with the `--init` option. If `--recursive` is specified, this command will recurse into the registered submodules, and update any nested submodules within. -If `--filter <filter spec>` is specified, the given partial clone filter will be +If `--filter <filter-spec>` is specified, the given partial clone filter will be applied to the submodule. See linkgit:git-rev-list[1] for details on filter specifications. -- diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 4e92308e85..43c68c2ec4 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -37,12 +37,12 @@ COMMANDS argument. Normally this command initializes the current directory. --T<trunk_subdir>;; ---trunk=<trunk_subdir>;; --t<tags_subdir>;; ---tags=<tags_subdir>;; --b<branches_subdir>;; ---branches=<branches_subdir>;; +-T<trunk-subdir>;; +--trunk=<trunk-subdir>;; +-t<tags-subdir>;; +--tags=<tags-subdir>;; +-b<branches-subdir>;; +--branches=<branches-subdir>;; -s;; --stdlayout;; These are optional command-line options for init. Each of @@ -726,9 +726,9 @@ ADVANCED OPTIONS when tracking a single URL. The 'log' and 'dcommit' commands no longer require this switch as an argument. --R<remote name>:: ---svn-remote <remote name>:: - Specify the [svn-remote "<remote name>"] section to use, +-R<remote-name>:: +--svn-remote <remote-name>:: + Specify the [svn-remote "<remote-name>"] section to use, this allows SVN multiple repositories to be tracked. Default: "svn" diff --git a/Documentation/git-switch.txt b/Documentation/git-switch.txt index c60fc9c138..f38e4c8afa 100644 --- a/Documentation/git-switch.txt +++ b/Documentation/git-switch.txt @@ -59,13 +59,18 @@ out at most one of `A` and `B`, in which case it defaults to `HEAD`. -c <new-branch>:: --create <new-branch>:: Create a new branch named `<new-branch>` starting at - `<start-point>` before switching to the branch. This is a - convenient shortcut for: + `<start-point>` before switching to the branch. This is the + transactional equivalent of + ------------ $ git branch <new-branch> $ git switch <new-branch> ------------ ++ +that is to say, the branch is not reset/created unless "git switch" is +successful (e.g., when the branch is in use in another worktree, not +just the current branch stays the same, but the branch is not reset to +the start-point, either). -C <new-branch>:: --force-create <new-branch>:: @@ -171,7 +176,7 @@ name, the guessing is aborted. You can explicitly give a name with `branch.autoSetupMerge` configuration variable is true. --orphan <new-branch>:: - Create a new 'orphan' branch, named `<new-branch>`. All + Create a new unborn branch, named `<new-branch>`. All tracked files are removed. --ignore-other-worktrees:: diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index d42efb3112..5fe519c31e 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -224,7 +224,7 @@ it in the repository configuration as follows: ------------------------------------- [user] - signingKey = <gpg-key_id> + signingKey = <gpg-key-id> ------------------------------------- `pager.tag` is only respected when listing tags, i.e., when `-l` is diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 93d76f5d66..2a240f53ba 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -99,7 +99,7 @@ command will refuse to create the worktree (unless `--force` is used). If `<commit-ish>` is omitted, neither `--detach`, or `--orphan` is used, and there are no valid local branches (or remote branches if `--guess-remote` is specified) then, as a convenience, the new worktree is -associated with a new orphan branch named `<branch>` (after +associated with a new unborn branch named `<branch>` (after `$(basename <path>)` if neither `-b` or `-B` is used) as if `--orphan` was passed to the command. In the event the repository has a remote and `--guess-remote` is used, but no remote or local branches exist, then the @@ -234,7 +234,7 @@ This can also be set up as the default behaviour by using the --orphan:: With `add`, make the new worktree and index empty, associating - the worktree with a new orphan/unborn branch named `<new-branch>`. + the worktree with a new unborn branch named `<new-branch>`. --porcelain:: With `list`, output in an easy-to-parse format for scripts. diff --git a/Documentation/git.txt b/Documentation/git.txt index 2535a30194..0d25224c96 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -202,7 +202,7 @@ If you just want to run git as if it was started in `<path>` then use Do not perform optional operations that require locks. This is equivalent to setting the `GIT_OPTIONAL_LOCKS` to `0`. ---list-cmds=group[,group...]:: +--list-cmds=<group>[,<group>...]:: List commands by group. This is an internal/experimental option and may change or be removed in the future. Supported groups are: builtins, parseopt (builtin commands that use @@ -556,6 +556,11 @@ double-quotes and respecting backslash escapes. E.g., the value is always used. The default is "sha1". See `--object-format` in linkgit:git-init[1]. +`GIT_DEFAULT_REF_FORMAT`:: + If this variable is set, the default reference backend format for new + repositories will be set to this value. The default is "files". + See `--ref-format` in linkgit:git-init[1]. + Git Commits ~~~~~~~~~~~ `GIT_AUTHOR_NAME`:: @@ -724,13 +729,12 @@ for further details. waiting for someone with sufficient permissions to fix it. `GIT_FLUSH`:: -// NEEDSWORK: make it into a usual Boolean environment variable - If this environment variable is set to "1", then commands such + If this Boolean environment variable is set to true, then commands such as 'git blame' (in incremental mode), 'git rev-list', 'git log', 'git check-attr' and 'git check-ignore' will force a flush of the output stream after each record have been flushed. If this - variable is set to "0", the output of these commands will be done + variable is set to false, the output of these commands will be done using completely buffered I/O. If this environment variable is not set, Git will choose buffered or record-oriented flushing based on whether stdout appears to be redirected to a file or not. @@ -838,7 +842,7 @@ of the SID and an optional counter (to avoid filename collisions). + In addition, if the variable is set to -`af_unix:[<socket_type>:]<absolute-pathname>`, Git will try +`af_unix:[<socket-type>:]<absolute-pathname>`, Git will try to open the path as a Unix Domain Socket. The socket type can be either `stream` or `dgram`. + @@ -917,9 +921,9 @@ for full details. avoid issues with stale commit-graphs that contain references to already-deleted commits, but comes with a performance penalty. + -The default is "true", which enables the aforementioned behavior. -Setting this to "false" disables the existence check. This can lead to -a performance improvement at the cost of consistency. +The default is "false", which disables the aforementioned behavior. +Setting this to "true" enables the existence check so that stale commits +will never be returned from the commit-graph at the cost of performance. `GIT_ALLOW_PROTOCOL`:: If set to a colon-separated list of protocols, behave as if @@ -1025,10 +1029,11 @@ When first created, objects are stored in individual files, but for efficiency may later be compressed together into "pack files". Named pointers called refs mark interesting points in history. A ref -may contain the SHA-1 name of an object or the name of another ref. Refs -with names beginning `ref/head/` contain the SHA-1 name of the most +may contain the SHA-1 name of an object or the name of another ref (the +latter is called a "symbolic ref"). +Refs with names beginning `refs/head/` contain the SHA-1 name of the most recent commit (or "head") of a branch under development. SHA-1 names of -tags of interest are stored under `ref/tags/`. A special ref named +tags of interest are stored under `refs/tags/`. A symbolic ref named `HEAD` contains the name of the currently checked-out branch. The index file is initialized with a list of all paths and, for each @@ -1071,7 +1076,7 @@ Authors ------- Git was started by Linus Torvalds, and is currently maintained by Junio C Hamano. Numerous contributions have come from the Git mailing list -<git@vger.kernel.org>. http://www.openhub.net/p/git/contributors/summary +<git@vger.kernel.org>. https://openhub.net/p/git/contributors/summary gives you a more complete list of contributors. If you have a clone of git.git itself, the diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 8c1793c148..4338d023d9 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -100,6 +100,21 @@ for a path to `Unspecified` state. This can be done by listing the name of the attribute prefixed with an exclamation point `!`. +RESERVED BUILTIN_* ATTRIBUTES +----------------------------- + +builtin_* is a reserved namespace for builtin attribute values. Any +user defined attributes under this namespace will be ignored and +trigger a warning. + +`builtin_objectmode` +~~~~~~~~~~~~~~~~~~~~ +This attribute is for filtering files by their file bit modes (40000, +120000, 160000, 100755, 100644). e.g. ':(attr:builtin_objectmode=160000)'. +You may also check these values with `git check-attr builtin_objectmode -- <file>`. +If the object is not in the index `git check-attr --cached` will return unspecified. + + EFFECTS ------- @@ -1122,11 +1137,11 @@ The `merge.*.name` variable gives the driver a human-readable name. The `merge.*.driver` variable's value is used to construct a -command to run to merge ancestor's version (`%O`), current +command to run to common ancestor's version (`%O`), current version (`%A`) and the other branches' version (`%B`). These three tokens are replaced with the names of temporary files that hold the contents of these versions when the command line is -built. Additionally, %L will be replaced with the conflict marker +built. Additionally, `%L` will be replaced with the conflict marker size (see below). The merge driver is expected to leave the result of the merge in @@ -1144,8 +1159,9 @@ When left unspecified, the driver itself is used for both internal merge and the final merge. The merge driver can learn the pathname in which the merged result -will be stored via placeholder `%P`. - +will be stored via placeholder `%P`. The conflict labels to be used +for the common ancestor, local head and other head can be passed by +using '%S', '%X' and '%Y` respectively. `conflict-marker-size` ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index c0b95256cc..2122aeb976 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -1089,7 +1089,7 @@ the remote repository URL in the local repository's config file like this: ------------------------------------------------ -$ git config remote.linus.url http://www.kernel.org/pub/scm/git/git.git/ +$ git config remote.linus.url https://git.kernel.org/pub/scm/git/git.git/ ------------------------------------------------ and use the "linus" keyword with 'git pull' instead of the full URL. diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt index 3cda2e07c2..642c51227b 100644 --- a/Documentation/gitdiffcore.txt +++ b/Documentation/gitdiffcore.txt @@ -245,20 +245,20 @@ diffcore-pickaxe: For Detecting Addition/Deletion of Specified String This transformation limits the set of filepairs to those that change specified strings between the preimage and the postimage in a certain -way. -S<block of text> and -G<regular expression> options are used to +way. -S<block-of-text> and -G<regular-expression> options are used to specify different ways these strings are sought. -"-S<block of text>" detects filepairs whose preimage and postimage +"-S<block-of-text>" detects filepairs whose preimage and postimage have different number of occurrences of the specified block of text. By definition, it will not detect in-file moves. Also, when a changeset moves a file wholesale without affecting the interesting string, diffcore-rename kicks in as usual, and `-S` omits the filepair (since the number of occurrences of that string didn't change in that rename-detected filepair). When used with `--pickaxe-regex`, treat -the <block of text> as an extended POSIX regular expression to match, +the <block-of-text> as an extended POSIX regular expression to match, instead of a literal string. -"-G<regular expression>" (mnemonic: grep) detects filepairs whose +"-G<regular-expression>" (mnemonic: grep) detects filepairs whose textual diff has an added or a deleted line that matches the given regular expression. This means that it will detect in-file (or what rename-detection considers the same file) moves, which is noise. The diff --git a/Documentation/gitformat-index.txt b/Documentation/gitformat-index.txt index 0773e5c380..145cace1fe 100644 --- a/Documentation/gitformat-index.txt +++ b/Documentation/gitformat-index.txt @@ -386,8 +386,8 @@ The remaining data of each directory block is grouped by type: long, "REUC" extension that is M-bytes long, followed by "EOIE", then the hash would be: - Hash("TREE" + <binary representation of N> + - "REUC" + <binary representation of M>) + Hash("TREE" + <binary-representation-of-N> + + "REUC" + <binary-representation-of-M>) == Index Entry Offset Table diff --git a/Documentation/gitformat-pack.txt b/Documentation/gitformat-pack.txt index 9fcb29a9c8..d6ae229be5 100644 --- a/Documentation/gitformat-pack.txt +++ b/Documentation/gitformat-pack.txt @@ -396,6 +396,15 @@ CHUNK DATA: is padded at the end with between 0 and 3 NUL bytes to make the chunk size a multiple of 4 bytes. + Bitmapped Packfiles (ID: {'B', 'T', 'M', 'P'}) + Stores a table of two 4-byte unsigned integers in network order. + Each table entry corresponds to a single pack (in the order that + they appear above in the `PNAM` chunk). The values for each table + entry are as follows: + - The first bit position (in pseudo-pack order, see below) to + contain an object from that pack. + - The number of bits whose objects are selected from that pack. + OID Fanout (ID: {'O', 'I', 'D', 'F'}) The ith entry, F[i], stores the number of OIDs with first byte at most i. Thus F[255] stores the total @@ -509,6 +518,73 @@ packs arranged in MIDX order (with the preferred pack coming first). The MIDX's reverse index is stored in the optional 'RIDX' chunk within the MIDX itself. +=== `BTMP` chunk + +The Bitmapped Packfiles (`BTMP`) chunk encodes additional information +about the objects in the multi-pack index's reachability bitmap. Recall +that objects from the MIDX are arranged in "pseudo-pack" order (see +above) for reachability bitmaps. + +From the example above, suppose we have packs "a", "b", and "c", with +10, 15, and 20 objects, respectively. In pseudo-pack order, those would +be arranged as follows: + + |a,0|a,1|...|a,9|b,0|b,1|...|b,14|c,0|c,1|...|c,19| + +When working with single-pack bitmaps (or, equivalently, multi-pack +reachability bitmaps with a preferred pack), linkgit:git-pack-objects[1] +performs ``verbatim'' reuse, attempting to reuse chunks of the bitmapped +or preferred packfile instead of adding objects to the packing list. + +When a chunk of bytes is reused from an existing pack, any objects +contained therein do not need to be added to the packing list, saving +memory and CPU time. But a chunk from an existing packfile can only be +reused when the following conditions are met: + + - The chunk contains only objects which were requested by the caller + (i.e. does not contain any objects which the caller didn't ask for + explicitly or implicitly). + + - All objects stored in non-thin packs as offset- or reference-deltas + also include their base object in the resulting pack. + +The `BTMP` chunk encodes the necessary information in order to implement +multi-pack reuse over a set of packfiles as described above. +Specifically, the `BTMP` chunk encodes three pieces of information (all +32-bit unsigned integers in network byte-order) for each packfile `p` +that is stored in the MIDX, as follows: + +`bitmap_pos`:: The first bit position (in pseudo-pack order) in the + multi-pack index's reachability bitmap occupied by an object from `p`. + +`bitmap_nr`:: The number of bit positions (including the one at + `bitmap_pos`) that encode objects from that pack `p`. + +For example, the `BTMP` chunk corresponding to the above example (with +packs ``a'', ``b'', and ``c'') would look like: + +[cols="1,2,2"] +|=== +| |`bitmap_pos` |`bitmap_nr` + +|packfile ``a'' +|`0` +|`10` + +|packfile ``b'' +|`10` +|`15` + +|packfile ``c'' +|`25` +|`20` +|=== + +With this information in place, we can treat each packfile as +individually reusable in the same fashion as verbatim pack reuse is +performed on individual packs prior to the implementation of the `BTMP` +chunk. + == cruft packs The cruft packs feature offer an alternative to Git's traditional mechanism of diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 883982e7a0..37f91d5b50 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -243,7 +243,7 @@ named remote is not being used both values will be the same. Information about what is to be pushed is provided on the hook's standard input with lines of the form: - <local ref> SP <local object name> SP <remote ref> SP <remote object name> LF + <local-ref> SP <local-object-name> SP <remote-ref> SP <remote-object-name> LF For instance, if the command +git push origin master:foreign+ were run the hook would receive a line like the following: @@ -251,9 +251,9 @@ hook would receive a line like the following: refs/heads/master 67890 refs/heads/foreign 12345 although the full object name would be supplied. If the foreign ref does not -yet exist the `<remote object name>` will be the all-zeroes object name. If a -ref is to be deleted, the `<local ref>` will be supplied as `(delete)` and the -`<local object name>` will be the all-zeroes object name. If the local commit +yet exist the `<remote-object-name>` will be the all-zeroes object name. If a +ref is to be deleted, the `<local-ref>` will be supplied as `(delete)` and the +`<local-object-name>` will be the all-zeroes object name. If the local commit was specified by something other than a name which could be expanded (such as `HEAD~`, or an object name) it will be supplied as it was originally given. diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt index c2213bb77b..35b3996029 100644 --- a/Documentation/gitk.txt +++ b/Documentation/gitk.txt @@ -8,7 +8,7 @@ gitk - The Git repository browser SYNOPSIS -------- [verse] -'gitk' [<options>] [<revision range>] [--] [<path>...] +'gitk' [<options>] [<revision-range>] [--] [<path>...] DESCRIPTION ----------- @@ -124,7 +124,7 @@ gitk-specific options range to show. The command is expected to print on its standard output a list of additional revisions to be shown, one per line. Use this instead of explicitly specifying a - '<revision range>' if the set of commits to show may vary + '<revision-range>' if the set of commits to show may vary between refreshes. --select-commit=<ref>:: diff --git a/Documentation/gitprotocol-capabilities.txt b/Documentation/gitprotocol-capabilities.txt index d6c6effc21..2cf7735be4 100644 --- a/Documentation/gitprotocol-capabilities.txt +++ b/Documentation/gitprotocol-capabilities.txt @@ -378,7 +378,7 @@ fetch-pack may send "filter" commands to request a partial clone or partial fetch and request that the server omit various objects from the packfile. -session-id=<session id> +session-id=<session-id> ----------------------- The server may advertise a session ID that can be used to identify this process diff --git a/Documentation/gitprotocol-http.txt b/Documentation/gitprotocol-http.txt index 21b73b7a1f..ec40a550cc 100644 --- a/Documentation/gitprotocol-http.txt +++ b/Documentation/gitprotocol-http.txt @@ -391,14 +391,14 @@ C: Start a queue, `c_pending`, ordered by commit time (popping newest C: Send one `$GIT_URL/git-upload-pack` request: - C: 0032want <want #1>............................... - C: 0032want <want #2>............................... + C: 0032want <want-#1>............................... + C: 0032want <want-#2>............................... .... - C: 0032have <common #1>............................. - C: 0032have <common #2>............................. + C: 0032have <common-#1>............................. + C: 0032have <common-#2>............................. .... - C: 0032have <have #1>............................... - C: 0032have <have #2>............................... + C: 0032have <have-#1>............................... + C: 0032have <have-#2>............................... .... C: 0000 @@ -512,7 +512,7 @@ Within the command portion of the request body clients SHOULD send the id obtained through ref discovery as old_id. update_request = command_list - "PACK" <binary data> + "PACK" <binary-data> command_list = PKT-LINE(command NUL cap_list LF) *(command_pkt) @@ -529,8 +529,8 @@ TODO: Document this further. REFERENCES ---------- -http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)] -http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1] +https://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)] +https://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1] SEE ALSO -------- diff --git a/Documentation/gitprotocol-v2.txt b/Documentation/gitprotocol-v2.txt index 8c1e7c61ea..0b800abd56 100644 --- a/Documentation/gitprotocol-v2.txt +++ b/Documentation/gitprotocol-v2.txt @@ -199,7 +199,7 @@ which can be used to limit the refs sent from the server. Additional features not supported in the base command will be advertised as the value of the command in the capability advertisement in the form -of a space separated list of features: "<command>=<feature 1> <feature 2>" +of a space separated list of features: "<command>=<feature-1> <feature-2>" ls-refs takes in the following arguments: @@ -245,7 +245,7 @@ addition of future extensions. Additional features not supported in the base command will be advertised as the value of the command in the capability advertisement in the form -of a space separated list of features: "<command>=<feature 1> <feature 2>" +of a space separated list of features: "<command>=<feature-1> <feature-2>" A `fetch` request can take the following arguments: @@ -363,7 +363,7 @@ can be included in the client's request as well as the potential addition of the 'packfile-uris' section in the server's response as explained below. - packfile-uris <comma-separated list of protocols> + packfile-uris <comma-separated-list-of-protocols> Indicates to the server that the client is willing to receive URIs of any of the given protocols in place of objects in the sent packfile. Before performing the connectivity check, the @@ -534,7 +534,7 @@ with objects using hash algorithm X. If not specified, the server is assumed to only handle SHA-1. If the client would like to use a hash algorithm other than SHA-1, it should specify its object-format string. -session-id=<session id> +session-id=<session-id> ~~~~~~~~~~~~~~~~~~~~~~~ The server may advertise a session ID that can be used to identify this process diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt index 1a2ef4c150..949cd8a31e 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.txt @@ -23,7 +23,9 @@ A Git repository comes in two different flavours: *Note*: Also you can have a plain text file `.git` at the root of your working tree, containing `gitdir: <path>` to point at the real -directory that has the repository. This mechanism is often used for +directory that has the repository. +This mechanism is called a 'gitfile' and is usually managed via the +`git submodule` and `git worktree` commands. It is often used for a working tree of a submodule checkout, to allow you in the containing superproject to `git checkout` a branch that does not have the submodule. The `checkout` has to remove the entire diff --git a/Documentation/gitsubmodules.txt b/Documentation/gitsubmodules.txt index 8400d591da..f7b5a25a0c 100644 --- a/Documentation/gitsubmodules.txt +++ b/Documentation/gitsubmodules.txt @@ -151,7 +151,7 @@ the superproject's `$GIT_DIR/config` file, so the superproject's history is not affected. This can be undone using `git submodule init`. * Deleted submodule: A submodule can be deleted by running -`git rm <submodule path> && git commit`. This can be undone +`git rm <submodule-path> && git commit`. This can be undone using `git revert`. + The deletion removes the superproject's tracking data, which are @@ -229,7 +229,7 @@ Workflow for a third party library git submodule add <URL> <path> # Occasionally update the submodule to a new version: - git -C <path> checkout <new version> + git -C <path> checkout <new-version> git add <path> git commit -m "update submodule to new version" diff --git a/Documentation/gitweb.conf.txt b/Documentation/gitweb.conf.txt index b078fef6f5..85983587fc 100644 --- a/Documentation/gitweb.conf.txt +++ b/Documentation/gitweb.conf.txt @@ -242,7 +242,7 @@ $mimetypes_file:: $highlight_bin:: Path to the highlight executable to use (it must be the one from - http://www.andre-simon.de[] due to assumptions about parameters and output). + http://andre-simon.de/zip/download.php[] due to assumptions about parameters and output). By default set to 'highlight'; set it to full path to highlight executable if it is not installed on your web server's PATH. Note that 'highlight' feature must be set for gitweb to actually @@ -343,7 +343,7 @@ $home_link_str:: Label for the "home link" at the top of all pages, leading to `$home_link` (usually the main gitweb page, which contains the projects list). It is used as the first component of gitweb's "breadcrumb trail": - `<home link> / <project> / <action>`. Can be set at build time using + `<home-link> / <project> / <action>`. Can be set at build time using the `GITWEB_HOME_LINK_STR` variable. By default it is set to "projects", as this link leads to the list of projects. Another popular choice is to set it to the name of site. Note that it is treated as raw HTML so it @@ -604,9 +604,9 @@ Many gitweb features can be enabled (or disabled) and configured using the Each `%feature` hash element is a hash reference and has the following structure: ---------------------------------------------------------------------- -"<feature_name>" => { - "sub" => <feature-sub (subroutine)>, - "override" => <allow-override (boolean)>, +"<feature-name>" => { + "sub" => <feature-sub-(subroutine)>, + "override" => <allow-override-(boolean)>, "default" => [ <options>... ] }, ---------------------------------------------------------------------- @@ -614,7 +614,7 @@ Some features cannot be overridden per project. For those features the structure of appropriate `%feature` hash element has a simpler form: ---------------------------------------------------------------------- -"<feature_name>" => { +"<feature-name>" => { "override" => 0, "default" => [ <options>... ] }, @@ -820,7 +820,7 @@ filesystem (i.e. "$projectroot/$project"), `%h` to the current hash (\'h' gitweb parameter) and `%b` to the current hash base (\'hb' gitweb parameter); `%%` expands to \'%'. + -For example, at the time this page was written, the http://repo.or.cz[] +For example, at the time this page was written, the https://repo.or.cz[] Git hosting site set it to the following to enable graphical log (using the third party tool *git-browser*): + diff --git a/Documentation/gitweb.txt b/Documentation/gitweb.txt index 1030e9667e..56d24a30a3 100644 --- a/Documentation/gitweb.txt +++ b/Documentation/gitweb.txt @@ -28,7 +28,7 @@ Gitweb provides a web interface to Git repositories. Its features include: revisions one at a time, viewing the history of the repository. * Finding commits whose commit messages match a given search term. -See http://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code, +See https://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code, browsed using gitweb itself. @@ -305,7 +305,7 @@ pathnames. In most general form such path_info (component) based gitweb URL looks like this: ----------------------------------------------------------------------- -.../gitweb.cgi/<repo>/<action>/<revision_from>:/<path_from>..<revision_to>:/<path_to>?<arguments> +.../gitweb.cgi/<repo>/<action>/<revision-from>:/<path-from>..<revision-to>:/<path-to>?<arguments> ----------------------------------------------------------------------- diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt index 65c89e7b3e..d71b199955 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -98,9 +98,8 @@ to point at the new commit. revision. [[def_commit-ish]]commit-ish (also committish):: - A <<def_commit_object,commit object>> or an - <<def_object,object>> that can be recursively dereferenced to - a commit object. + A <<def_commit_object,commit object>> or an <<def_object,object>> that + can be recursively <<def_dereference,dereferenced>> to a commit object. The following are all commit-ishes: a commit object, a <<def_tag_object,tag object>> that points to a commit @@ -125,6 +124,25 @@ to point at the new commit. dangling object has no references to it from any reference or <<def_object,object>> in the <<def_repository,repository>>. +[[def_dereference]]dereference:: + Referring to a <<def_symref,symbolic ref>>: the action of accessing the + <<def_ref,reference>> pointed at by a symbolic ref. Recursive + dereferencing involves repeating the aforementioned process on the + resulting ref until a non-symbolic reference is found. ++ +Referring to a <<def_tag_object,tag object>>: the action of accessing the +<<def_object,object>> a tag points at. Tags are recursively dereferenced by +repeating the operation on the result object until the result has either a +specified <<def_object_type,object type>> (where applicable) or any non-"tag" +object type. A synonym for "recursive dereference" in the context of tags is +"<<def_peel,peel>>". ++ +Referring to a <<def_commit_object,commit object>>: the action of accessing +the commit's tree object. Commits cannot be dereferenced recursively. ++ +Unless otherwise specified, "dereferencing" as it used in the context of Git +commands or protocols is implicitly recursive. + [[def_detached_HEAD]]detached HEAD:: Normally the <<def_HEAD,HEAD>> stores the name of a <<def_branch,branch>>, and commands that operate on the @@ -184,6 +202,8 @@ current branch integrates with) obviously do not work, as there is no [[def_gitfile]]gitfile:: A plain file `.git` at the root of a working tree that points at the directory that is the real repository. + For proper use see linkgit:git-worktree[1] or linkgit:git-submodule[1]. + For syntax see linkgit:gitrepository-layout[5]. [[def_grafts]]grafts:: Grafts enable two otherwise different lines of development to be joined @@ -294,6 +314,12 @@ This commit is referred to as a "merge commit", or sometimes just a [[def_octopus]]octopus:: To <<def_merge,merge>> more than two <<def_branch,branches>>. +[[def_orphan]]orphan:: + The act of getting on a <<def_branch,branch>> that does not + exist yet (i.e., an <<def_unborn,unborn>> branch). After + such an operation, the commit first created becomes a commit + without a parent, starting a new history. + [[def_origin]]origin:: The default upstream <<def_repository,repository>>. Most projects have at least one upstream project which they track. By default @@ -444,6 +470,10 @@ exclude;; of the logical predecessor(s) in the line of development, i.e. its parents. +[[def_peel]]peel:: + The action of recursively <<def_dereference,dereferencing>> a + <<def_tag_object,tag object>>. + [[def_pickaxe]]pickaxe:: The term <<def_pickaxe,pickaxe>> refers to an option to the diffcore routines that help select changes that add or delete a given text @@ -608,6 +638,20 @@ The most notable example is `HEAD`. An <<def_object,object>> used to temporarily store the contents of a <<def_dirty,dirty>> working directory and the index for future reuse. +[[def_special_ref]]special ref:: + A ref that has different semantics than normal refs. These refs can be + accessed via normal Git commands but may not behave the same as a + normal ref in some cases. ++ +The following special refs are known to Git: + + - "`FETCH_HEAD`" is written by linkgit:git-fetch[1] or linkgit:git-pull[1]. It + may refer to multiple object IDs. Each object ID is annotated with metadata + indicating where it was fetched from and its fetch status. + + - "`MERGE_HEAD`" is written by linkgit:git-merge[1] when resolving merge + conflicts. It contains all commit IDs which are being merged. + [[def_submodule]]submodule:: A <<def_repository,repository>> that holds the history of a separate project inside another repository (the latter of @@ -620,12 +664,11 @@ The most notable example is `HEAD`. copies of) commit objects of the contained submodules. [[def_symref]]symref:: - Symbolic reference: instead of containing the <<def_SHA1,SHA-1>> - id itself, it is of the format 'ref: refs/some/thing' and when - referenced, it recursively dereferences to this reference. - '<<def_HEAD,HEAD>>' is a prime example of a symref. Symbolic - references are manipulated with the linkgit:git-symbolic-ref[1] - command. + Symbolic reference: instead of containing the <<def_SHA1,SHA-1>> id + itself, it is of the format 'ref: refs/some/thing' and when referenced, + it recursively <<def_dereference,dereferences>> to this reference. + '<<def_HEAD,HEAD>>' is a prime example of a symref. Symbolic references + are manipulated with the linkgit:git-symbolic-ref[1] command. [[def_tag]]tag:: A <<def_ref,ref>> under `refs/tags/` namespace that points to an @@ -661,11 +704,11 @@ The most notable example is `HEAD`. <<def_tree,tree>> is equivalent to a <<def_directory,directory>>. [[def_tree-ish]]tree-ish (also treeish):: - A <<def_tree_object,tree object>> or an <<def_object,object>> - that can be recursively dereferenced to a tree object. - Dereferencing a <<def_commit_object,commit object>> yields the - tree object corresponding to the <<def_revision,revision>>'s - top <<def_directory,directory>>. + A <<def_tree_object,tree object>> or an <<def_object,object>> that can + be recursively <<def_dereference,dereferenced>> to a tree object. + Dereferencing a <<def_commit_object,commit object>> yields the tree + object corresponding to the <<def_revision,revision>>'s top + <<def_directory,directory>>. The following are all tree-ishes: a <<def_commit-ish,commit-ish>>, a tree object, @@ -674,6 +717,18 @@ The most notable example is `HEAD`. object, etc. +[[def_unborn]]unborn:: + The <<def_HEAD,HEAD>> can point at a <<def_branch,branch>> + that does not yet exist and that does not have any commit on + it yet, and such a branch is called an unborn branch. The + most typical way users encounter an unborn branch is by + creating a repository anew without cloning from elsewhere. + The HEAD would point at the 'main' (or 'master', depending + on your configuration) branch that is yet to be born. Also + some operations can get you on an unborn branch with their + <<def_orphan,orphan>> option. + + [[def_unmerged_index]]unmerged index:: An <<def_index,index>> which contains unmerged <<def_index_entry,index entries>>. diff --git a/Documentation/howto/keep-canonical-history-correct.txt b/Documentation/howto/keep-canonical-history-correct.txt index 35d48ef714..5f800fd85a 100644 --- a/Documentation/howto/keep-canonical-history-correct.txt +++ b/Documentation/howto/keep-canonical-history-correct.txt @@ -213,4 +213,4 @@ The procedure will result in a history that looks like this: B0--B1---------B2 ------------ -See also http://git-blame.blogspot.com/2013/09/fun-with-first-parent-history.html +See also https://git-blame.blogspot.com/2013/09/fun-with-first-parent-history.html diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index d8f7cd7ca0..3eaefc4e94 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -191,7 +191,7 @@ endif::git-pull[] --autostash:: --no-autostash:: Automatically create a temporary stash entry before the operation - begins, record it in the special ref `MERGE_AUTOSTASH` + begins, record it in the ref `MERGE_AUTOSTASH` and apply it after the operation ends. This means that you can run the operation on a dirty worktree. However, use with care: the final stash application after a successful diff --git a/Documentation/mergetools/vimdiff.txt b/Documentation/mergetools/vimdiff.txt index d1a4c468e6..befa86d692 100644 --- a/Documentation/mergetools/vimdiff.txt +++ b/Documentation/mergetools/vimdiff.txt @@ -177,7 +177,8 @@ Instead of `--tool=vimdiff`, you can also use one of these other variants: 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` +`mergetool.nvimdiff.layout` instead of `mergetool.vimdiff.layout` (though the +latter will be used as fallback if the variant-specific one is not set). 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: diff --git a/Documentation/ref-storage-format.txt b/Documentation/ref-storage-format.txt new file mode 100644 index 0000000000..14fff8a9c6 --- /dev/null +++ b/Documentation/ref-storage-format.txt @@ -0,0 +1,3 @@ +* `files` for loose files with packed-refs. This is the default. +* `reftable` for the reftable format. This format is experimental and its + internals are subject to change. diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 2bf239ff03..a583b52c61 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -947,10 +947,10 @@ ifdef::git-rev-list[] + The form '--filter=blob:none' omits all blobs. + -The form '--filter=blob:limit=<n>[kmg]' omits blobs larger than n bytes -or units. n may be zero. The suffixes k, m, and g can be used to name -units in KiB, MiB, or GiB. For example, 'blob:limit=1k' is the same -as 'blob:limit=1024'. +The form '--filter=blob:limit=<n>[kmg]' omits blobs of size at least n +bytes or units. n may be zero. The suffixes k, m, and g can be used +to name units in KiB, MiB, or GiB. For example, 'blob:limit=1k' +is the same as 'blob:limit=1024'. + The form '--filter=object:type=(tag|commit|tree|blob)' omits all objects which are not of the requested type. diff --git a/Documentation/signoff-option.txt b/Documentation/signoff-option.txt index 12aa2333e4..d98758f3cb 100644 --- a/Documentation/signoff-option.txt +++ b/Documentation/signoff-option.txt @@ -9,7 +9,7 @@ endif::git-commit[] the committer has the rights to submit the work under the project's license or agrees to some contributor representation, such as a Developer Certificate of Origin. - (See http://developercertificate.org for the one used by the + (See https://developercertificate.org for the one used by the Linux kernel and Git projects.) Consult the documentation or leadership of the project to which you're contributing to understand how the signoffs are used in that project. diff --git a/Documentation/technical/repository-version.txt b/Documentation/technical/repository-version.txt index 045a76756f..47281420fc 100644 --- a/Documentation/technical/repository-version.txt +++ b/Documentation/technical/repository-version.txt @@ -100,3 +100,9 @@ If set, by default "git config" reads from both "config" and multiple working directory mode, "config" file is shared while "config.worktree" is per-working directory (i.e., it's in GIT_COMMON_DIR/worktrees/<id>/config.worktree) + +==== `refStorage` + +Specifies the file format for the ref database. The valid values are +`files` (loose references with a packed-refs file) and `reftable` (see +Documentation/technical/reftable.txt). diff --git a/Documentation/technical/unit-tests.txt b/Documentation/technical/unit-tests.txt new file mode 100644 index 0000000000..206037ffb1 --- /dev/null +++ b/Documentation/technical/unit-tests.txt @@ -0,0 +1,240 @@ += Unit Testing + +In our current testing environment, we spend a significant amount of effort +crafting end-to-end tests for error conditions that could easily be captured by +unit tests (or we simply forgo some hard-to-setup and rare error conditions). +Unit tests additionally provide stability to the codebase and can simplify +debugging through isolation. Writing unit tests in pure C, rather than with our +current shell/test-tool helper setup, simplifies test setup, simplifies passing +data around (no shell-isms required), and reduces testing runtime by not +spawning a separate process for every test invocation. + +We believe that a large body of unit tests, living alongside the existing test +suite, will improve code quality for the Git project. + +== Definitions + +For the purposes of this document, we'll use *test framework* to refer to +projects that support writing test cases and running tests within the context +of a single executable. *Test harness* will refer to projects that manage +running multiple executables (each of which may contain multiple test cases) and +aggregating their results. + +In reality, these terms are not strictly defined, and many of the projects +discussed below contain features from both categories. + +For now, we will evaluate projects solely on their framework features. Since we +are relying on having TAP output (see below), we can assume that any framework +can be made to work with a harness that we can choose later. + + +== Summary + +We believe the best way forward is to implement a custom TAP framework for the +Git project. We use a version of the framework originally proposed in +https://lore.kernel.org/git/c902a166-98ce-afba-93f2-ea6027557176@gmail.com/[1]. + +See the <<framework-selection,Framework Selection>> section below for the +rationale behind this decision. + + +== Choosing a test harness + +During upstream discussion, it was occasionally noted that `prove` provides many +convenient features, such as scheduling slower tests first, or re-running +previously failed tests. + +While we already support the use of `prove` as a test harness for the shell +tests, it is not strictly required. The t/Makefile allows running shell tests +directly (though with interleaved output if parallelism is enabled). Git +developers who wish to use `prove` as a more advanced harness can do so by +setting DEFAULT_TEST_TARGET=prove in their config.mak. + +We will follow a similar approach for unit tests: by default the test +executables will be run directly from the t/Makefile, but `prove` can be +configured with DEFAULT_UNIT_TEST_TARGET=prove. + + +[[framework-selection]] +== Framework selection + +There are a variety of features we can use to rank the candidate frameworks, and +those features have different priorities: + +* Critical features: we probably won't consider a framework without these +** Can we legally / easily use the project? +*** <<license,License>> +*** <<vendorable-or-ubiquitous,Vendorable or ubiquitous>> +*** <<maintainable-extensible,Maintainable / extensible>> +*** <<major-platform-support,Major platform support>> +** Does the project support our bare-minimum needs? +*** <<tap-support,TAP support>> +*** <<diagnostic-output,Diagnostic output>> +*** <<runtime-skippable-tests,Runtime-skippable tests>> +* Nice-to-have features: +** <<parallel-execution,Parallel execution>> +** <<mock-support,Mock support>> +** <<signal-error-handling,Signal & error-handling>> +* Tie-breaker stats +** <<project-kloc,Project KLOC>> +** <<adoption,Adoption>> + +[[license]] +=== License + +We must be able to legally use the framework in connection with Git. As Git is +licensed only under GPLv2, we must eliminate any LGPLv3, GPLv3, or Apache 2.0 +projects. + +[[vendorable-or-ubiquitous]] +=== Vendorable or ubiquitous + +We want to avoid forcing Git developers to install new tools just to run unit +tests. Any prospective frameworks and harnesses must either be vendorable +(meaning, we can copy their source directly into Git's repository), or so +ubiquitous that it is reasonable to expect that most developers will have the +tools installed already. + +[[maintainable-extensible]] +=== Maintainable / extensible + +It is unlikely that any pre-existing project perfectly fits our needs, so any +project we select will need to be actively maintained and open to accepting +changes. Alternatively, assuming we are vendoring the source into our repo, it +must be simple enough that Git developers can feel comfortable making changes as +needed to our version. + +In the comparison table below, "True" means that the framework seems to have +active developers, that it is simple enough that Git developers can make changes +to it, and that the project seems open to accepting external contributions (or +that it is vendorable). "Partial" means that at least one of the above +conditions holds. + +[[major-platform-support]] +=== Major platform support + +At a bare minimum, unit-testing must work on Linux, MacOS, and Windows. + +In the comparison table below, "True" means that it works on all three major +platforms with no issues. "Partial" means that there may be annoyances on one or +more platforms, but it is still usable in principle. + +[[tap-support]] +=== TAP support + +The https://testanything.org/[Test Anything Protocol] is a text-based interface +that allows tests to communicate with a test harness. It is already used by +Git's integration test suite. Supporting TAP output is a mandatory feature for +any prospective test framework. + +In the comparison table below, "True" means this is natively supported. +"Partial" means TAP output must be generated by post-processing the native +output. + +Frameworks that do not have at least Partial support will not be evaluated +further. + +[[diagnostic-output]] +=== Diagnostic output + +When a test case fails, the framework must generate enough diagnostic output to +help developers find the appropriate test case in source code in order to debug +the failure. + +[[runtime-skippable-tests]] +=== Runtime-skippable tests + +Test authors may wish to skip certain test cases based on runtime circumstances, +so the framework should support this. + +[[parallel-execution]] +=== Parallel execution + +Ideally, we will build up a significant collection of unit test cases, most +likely split across multiple executables. It will be necessary to run these +tests in parallel to enable fast develop-test-debug cycles. + +In the comparison table below, "True" means that individual test cases within a +single test executable can be run in parallel. We assume that executable-level +parallelism can be handled by the test harness. + +[[mock-support]] +=== Mock support + +Unit test authors may wish to test code that interacts with objects that may be +inconvenient to handle in a test (e.g. interacting with a network service). +Mocking allows test authors to provide a fake implementation of these objects +for more convenient tests. + +[[signal-error-handling]] +=== Signal & error handling + +The test framework should fail gracefully when test cases are themselves buggy +or when they are interrupted by signals during runtime. + +[[project-kloc]] +=== Project KLOC + +The size of the project, in thousands of lines of code as measured by +https://dwheeler.com/sloccount/[sloccount] (rounded up to the next multiple of +1,000). As a tie-breaker, we probably prefer a project with fewer LOC. + +[[adoption]] +=== Adoption + +As a tie-breaker, we prefer a more widely-used project. We use the number of +GitHub / GitLab stars to estimate this. + + +=== Comparison + +:true: [lime-background]#True# +:false: [red-background]#False# +:partial: [yellow-background]#Partial# + +:gpl: [lime-background]#GPL v2# +:isc: [lime-background]#ISC# +:mit: [lime-background]#MIT# +:expat: [lime-background]#Expat# +:lgpl: [lime-background]#LGPL v2.1# + +:custom-impl: https://lore.kernel.org/git/c902a166-98ce-afba-93f2-ea6027557176@gmail.com/[Custom Git impl.] +:greatest: https://github.com/silentbicycle/greatest[Greatest] +:criterion: https://github.com/Snaipe/Criterion[Criterion] +:c-tap: https://github.com/rra/c-tap-harness/[C TAP] +:check: https://libcheck.github.io/check/[Check] + +[format="csv",options="header",width="33%",subs="specialcharacters,attributes,quotes,macros"] +|===== +Framework,"<<license,License>>","<<vendorable-or-ubiquitous,Vendorable or ubiquitous>>","<<maintainable-extensible,Maintainable / extensible>>","<<major-platform-support,Major platform support>>","<<tap-support,TAP support>>","<<diagnostic-output,Diagnostic output>>","<<runtime--skippable-tests,Runtime- skippable tests>>","<<parallel-execution,Parallel execution>>","<<mock-support,Mock support>>","<<signal-error-handling,Signal & error handling>>","<<project-kloc,Project KLOC>>","<<adoption,Adoption>>" +{custom-impl},{gpl},{true},{true},{true},{true},{true},{true},{false},{false},{false},1,0 +{greatest},{isc},{true},{partial},{true},{partial},{true},{true},{false},{false},{false},3,1400 +{criterion},{mit},{false},{partial},{true},{true},{true},{true},{true},{false},{true},19,1800 +{c-tap},{expat},{true},{partial},{partial},{true},{false},{true},{false},{false},{false},4,33 +{check},{lgpl},{false},{partial},{true},{true},{true},{false},{false},{false},{true},17,973 +|===== + +=== Additional framework candidates + +Several suggested frameworks have been eliminated from consideration: + +* Incompatible licenses: +** https://github.com/zorgnax/libtap[libtap] (LGPL v3) +** https://cmocka.org/[cmocka] (Apache 2.0) +* Missing source: https://www.kindahl.net/mytap/doc/index.html[MyTap] +* No TAP support: +** https://nemequ.github.io/munit/[µnit] +** https://github.com/google/cmockery[cmockery] +** https://github.com/lpabon/cmockery2[cmockery2] +** https://github.com/ThrowTheSwitch/Unity[Unity] +** https://github.com/siu/minunit[minunit] +** https://cunit.sourceforge.net/[CUnit] + + +== Milestones + +* Add useful tests of library-like code +* Integrate with + https://lore.kernel.org/git/20230502211454.1673000-1-calvinwan@google.com/[stdlib + work] +* Run alongside regular `make test` target diff --git a/Documentation/trace2-target-values.txt b/Documentation/trace2-target-values.txt index 3985b6d3c2..06f1953313 100644 --- a/Documentation/trace2-target-values.txt +++ b/Documentation/trace2-target-values.txt @@ -5,7 +5,7 @@ * `<absolute-pathname>` - Writes to the file in append mode. If the target already exists and is a directory, the traces will be written to files (one per process) underneath the given directory. -* `af_unix:[<socket_type>:]<absolute-pathname>` - Write to a +* `af_unix:[<socket-type>:]<absolute-pathname>` - Write to a Unix DomainSocket (on platforms that support them). Socket type can be either `stream` or `dgram`; if omitted Git will try both. diff --git a/Documentation/urls.txt b/Documentation/urls.txt index 4e79c1589e..ce671f812d 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.txt @@ -73,8 +73,8 @@ use will be rewritten into URLs that work), you can create a configuration section of the form: ------------ - [url "<actual url base>"] - insteadOf = <other url base> + [url "<actual-url-base>"] + insteadOf = <other-url-base> ------------ For example, with this: @@ -92,8 +92,8 @@ If you want to rewrite URLs for push only, you can create a configuration section of the form: ------------ - [url "<actual url base>"] - pushInsteadOf = <other url base> + [url "<actual-url-base>"] + pushInsteadOf = <other-url-base> ------------ For example, with this: diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index d8dbe6b56d..6433903491 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1344,7 +1344,7 @@ $ git diff --theirs file.txt # same as the above. ------------------------------------------------- When using the 'ort' merge strategy (the default), before updating the working -tree with the result of the merge, Git writes a special ref named AUTO_MERGE +tree with the result of the merge, Git writes a ref named AUTO_MERGE reflecting the state of the tree it is about to write. Conflicted paths with textual conflicts that could not be automatically merged are written to this tree with conflict markers, just as in the working tree. AUTO_MERGE can thus be @@ -4100,8 +4100,8 @@ independently of the contents or the type of the object: all objects can be validated by verifying that (a) their hashes match the content of the file and (b) the object successfully inflates to a stream of bytes that forms a sequence of -`<ascii type without space> + <space> + <ascii decimal size> + -<byte\0> + <binary object data>`. +`<ascii-type-without-space> + <space> + <ascii-decimal-size> + +<byte\0> + <binary-object-data>`. The structured objects can further have their structure and connectivity to other objects verified. This is generally done with diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index e54492f827..c9d1d29082 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.43.0-rc1 +DEF_VER=v2.44.0 LF=' ' @@ -11,7 +11,7 @@ LF=' if test -f version then VN=$(cat version) || VN="$DEF_VER" -elif test -d ${GIT_DIR:-.git} -o -f .git && +elif { test -d "${GIT_DIR:-.git}" || test -f .git; } && VN=$(git describe --match "v[0-9]*" HEAD 2>/dev/null) && case "$VN" in *$LF*) (exit 1) ;; @@ -119,12 +119,12 @@ Issues of note: - A POSIX-compliant shell is required to run some scripts needed for everyday use (e.g. "bisect", "request-pull"). - - "Perl" version 5.8 or later is needed to use some of the + - "Perl" version 5.8.1 or later is needed to use some of the features (e.g. sending patches using "git send-email", interacting with svn repositories with "git svn"). If you can live without these, use NO_PERL. Note that recent releases of Redhat/Fedora are reported to ship Perl binary package with some - core modules stripped away (see http://lwn.net/Articles/477234/), + core modules stripped away (see https://lwn.net/Articles/477234/), so you might need to install additional packages other than Perl itself, e.g. Digest::MD5, File::Spec, File::Temp, Net::Domain, Net::SMTP, and Time::HiRes. @@ -186,7 +186,7 @@ include shared.mak # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. # # Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback, -# as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) +# as the compiler can crash (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) # # Define USE_NSEC below if you want git to care about sub-second file mtimes # and ctimes. Note that you need recent glibc (at least 2.2.4) for this. On @@ -682,6 +682,9 @@ TEST_BUILTINS_OBJS = TEST_OBJS = TEST_PROGRAMS_NEED_X = THIRD_PARTY_SOURCES = +UNIT_TEST_PROGRAMS = +UNIT_TEST_DIR = t/unit-tests +UNIT_TEST_BIN = $(UNIT_TEST_DIR)/bin # Having this variable in your environment would break pipelines because # you cause "cd" to echo its destination to stdout. It can also take @@ -749,7 +752,12 @@ SCRIPTS = $(SCRIPT_SH_GEN) \ ETAGS_TARGET = TAGS +# If you add a new fuzzer, please also make sure to run it in +# ci/run-build-and-minimal-fuzzers.sh so that we make sure it still links and +# runs in the future. +FUZZ_OBJS += oss-fuzz/dummy-cmd-main.o FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o +FUZZ_OBJS += oss-fuzz/fuzz-date.o FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o .PHONY: fuzz-objs @@ -758,7 +766,7 @@ fuzz-objs: $(FUZZ_OBJS) # Always build fuzz objects even if not testing, to prevent bit-rot. all:: $(FUZZ_OBJS) -FUZZ_PROGRAMS += $(patsubst %.o,%,$(FUZZ_OBJS)) +FUZZ_PROGRAMS += $(patsubst %.o,%,$(filter-out %dummy-cmd-main.o,$(FUZZ_OBJS))) # Empty... EXTRA_PROGRAMS = @@ -788,7 +796,6 @@ TEST_BUILTINS_OBJS += test-chmtime.o TEST_BUILTINS_OBJS += test-config.o TEST_BUILTINS_OBJS += test-crontab.o TEST_BUILTINS_OBJS += test-csprng.o -TEST_BUILTINS_OBJS += test-ctype.o TEST_BUILTINS_OBJS += test-date.o TEST_BUILTINS_OBJS += test-delta.o TEST_BUILTINS_OBJS += test-dir-iterator.o @@ -799,7 +806,6 @@ TEST_BUILTINS_OBJS += test-dump-split-index.o TEST_BUILTINS_OBJS += test-dump-untracked-cache.o TEST_BUILTINS_OBJS += test-env-helper.o TEST_BUILTINS_OBJS += test-example-decorate.o -TEST_BUILTINS_OBJS += test-fast-rebase.o TEST_BUILTINS_OBJS += test-find-pack.o TEST_BUILTINS_OBJS += test-fsmonitor-client.o TEST_BUILTINS_OBJS += test-genrandom.o @@ -825,7 +831,6 @@ TEST_BUILTINS_OBJS += test-partial-clone.o TEST_BUILTINS_OBJS += test-path-utils.o TEST_BUILTINS_OBJS += test-pcre2-config.o TEST_BUILTINS_OBJS += test-pkt-line.o -TEST_BUILTINS_OBJS += test-prio-queue.o TEST_BUILTINS_OBJS += test-proc-receive.o TEST_BUILTINS_OBJS += test-progress.o TEST_BUILTINS_OBJS += test-reach.o @@ -1121,6 +1126,7 @@ LIB_OBJS += reflog.o LIB_OBJS += refs.o LIB_OBJS += refs/debug.o LIB_OBJS += refs/files-backend.o +LIB_OBJS += refs/reftable-backend.o LIB_OBJS += refs/iterator.o LIB_OBJS += refs/packed-backend.o LIB_OBJS += refs/ref-cache.o @@ -1290,6 +1296,7 @@ BUILTIN_OBJS += builtin/remote-fd.o BUILTIN_OBJS += builtin/remote.o BUILTIN_OBJS += builtin/repack.o BUILTIN_OBJS += builtin/replace.o +BUILTIN_OBJS += builtin/replay.o BUILTIN_OBJS += builtin/rerere.o BUILTIN_OBJS += builtin/reset.o BUILTIN_OBJS += builtin/rev-list.o @@ -1335,6 +1342,15 @@ THIRD_PARTY_SOURCES += compat/regex/% THIRD_PARTY_SOURCES += sha1collisiondetection/% THIRD_PARTY_SOURCES += sha1dc/% +UNIT_TEST_PROGRAMS += t-basic +UNIT_TEST_PROGRAMS += t-mem-pool +UNIT_TEST_PROGRAMS += t-strbuf +UNIT_TEST_PROGRAMS += t-ctype +UNIT_TEST_PROGRAMS += t-prio-queue +UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS)) +UNIT_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS)) +UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o + # xdiff and reftable libs may in turn depend on what is in libgit.a GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE) EXTLIBS = @@ -1575,7 +1591,7 @@ endif ifdef LIBPCREDIR BASIC_CFLAGS += -I$(LIBPCREDIR)/include - EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib) + EXTLIBS += $(call libpath_template,$(LIBPCREDIR)/$(lib)) endif ifdef HAVE_ALLOCA_H @@ -1595,7 +1611,7 @@ else ifdef CURLDIR # Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case. CURL_CFLAGS = -I$(CURLDIR)/include - CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib) + CURL_LIBCURL = $(call libpath_template,$(CURLDIR)/$(lib)) else CURL_CFLAGS = CURL_LIBCURL = @@ -1631,7 +1647,7 @@ else ifndef NO_EXPAT ifdef EXPATDIR BASIC_CFLAGS += -I$(EXPATDIR)/include - EXPAT_LIBEXPAT = -L$(EXPATDIR)/$(lib) $(CC_LD_DYNPATH)$(EXPATDIR)/$(lib) -lexpat + EXPAT_LIBEXPAT = $(call libpath_template,$(EXPATDIR)/$(lib)) -lexpat else EXPAT_LIBEXPAT = -lexpat endif @@ -1644,7 +1660,7 @@ IMAP_SEND_LDFLAGS += $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO) ifdef ZLIB_PATH BASIC_CFLAGS += -I$(ZLIB_PATH)/include - EXTLIBS += -L$(ZLIB_PATH)/$(lib) $(CC_LD_DYNPATH)$(ZLIB_PATH)/$(lib) + EXTLIBS += $(call libpath_template,$(ZLIB_PATH)/$(lib)) endif EXTLIBS += -lz @@ -1652,7 +1668,7 @@ ifndef NO_OPENSSL OPENSSL_LIBSSL = -lssl ifdef OPENSSLDIR BASIC_CFLAGS += -I$(OPENSSLDIR)/include - OPENSSL_LINK = -L$(OPENSSLDIR)/$(lib) $(CC_LD_DYNPATH)$(OPENSSLDIR)/$(lib) + OPENSSL_LINK = $(call libpath_template,$(OPENSSLDIR)/$(lib)) else OPENSSL_LINK = endif @@ -1679,7 +1695,7 @@ ifndef NO_ICONV ifdef NEEDS_LIBICONV ifdef ICONVDIR BASIC_CFLAGS += -I$(ICONVDIR)/include - ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib) + ICONV_LINK = $(call libpath_template,$(ICONVDIR)/$(lib)) else ICONV_LINK = endif @@ -2342,7 +2358,7 @@ profile-fast: profile-clean all:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS ifneq (,$X) - $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';) + $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), if test ! -d '$p' && test ! '$p' -ef '$p$X'; then $(RM) '$p'; fi;) endif all:: @@ -2676,6 +2692,7 @@ OBJECTS += $(TEST_OBJS) OBJECTS += $(XDIFF_OBJS) OBJECTS += $(FUZZ_OBJS) OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS) +OBJECTS += $(UNIT_TEST_OBJS) ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o @@ -2723,7 +2740,7 @@ $(OBJECTS): %.o: %.c GIT-CFLAGS $(missing_dep_dirs) $(missing_compdb_dir) ifdef USE_COMPUTED_HEADER_DEPENDENCIES # Take advantage of gcc's on-the-fly dependency generation -# See <http://gcc.gnu.org/gcc-3.0/features.html>. +# See <https://gcc.gnu.org/gcc-3.0/features.html>. dep_files_present := $(wildcard $(dep_files)) ifneq ($(dep_files_present),) include $(dep_files_present) @@ -3178,7 +3195,7 @@ endif test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X)) -all:: $(TEST_PROGRAMS) $(test_bindir_programs) +all:: $(TEST_PROGRAMS) $(test_bindir_programs) $(UNIT_TEST_PROGS) bin-wrappers/%: wrap-for-bin.sh $(call mkdir_p_parent_template) @@ -3604,12 +3621,12 @@ rpm:: .PHONY: rpm ifneq ($(INCLUDE_DLLS_IN_ARTIFACTS),) -OTHER_PROGRAMS += $(shell echo *.dll t/helper/*.dll) +OTHER_PROGRAMS += $(shell echo *.dll t/helper/*.dll t/unit-tests/bin/*.dll) endif artifacts-tar:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) \ GIT-BUILD-OPTIONS $(TEST_PROGRAMS) $(test_bindir_programs) \ - $(MOFILES) + $(UNIT_TEST_PROGS) $(MOFILES) $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) \ SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)' test -n "$(ARTIFACTS_DIRECTORY)" @@ -3664,7 +3681,7 @@ cocciclean: $(RM) contrib/coccinelle/*.cocci.patch clean: profile-clean coverage-clean cocciclean - $(RM) -r .build + $(RM) -r .build $(UNIT_TEST_BIN) $(RM) po/git.pot po/git-core.pot $(RM) git.res $(RM) $(OBJECTS) @@ -3838,15 +3855,26 @@ cover_db_html: cover_db # # make CC=clang CXX=clang++ \ # CFLAGS="-fsanitize=fuzzer-no-link,address" \ -# LIB_FUZZING_ENGINE="-fsanitize=fuzzer" \ +# LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \ # fuzz-all # -FUZZ_CXXFLAGS ?= $(CFLAGS) +FUZZ_CXXFLAGS ?= $(ALL_CFLAGS) .PHONY: fuzz-all -$(FUZZ_PROGRAMS): all - $(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) $(LIB_OBJS) $(BUILTIN_OBJS) \ - $(XDIFF_OBJS) $(EXTLIBS) git.o $@.o $(LIB_FUZZING_ENGINE) -o $@ +$(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS + $(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) -o $@ $(ALL_LDFLAGS) \ + -Wl,--allow-multiple-definition \ + $(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE) fuzz-all: $(FUZZ_PROGRAMS) + +$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS + $(call mkdir_p_parent_template) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ + $(filter %.o,$^) $(filter %.a,$^) $(LIBS) + +.PHONY: build-unit-tests unit-tests +build-unit-tests: $(UNIT_TEST_PROGS) +unit-tests: $(UNIT_TEST_PROGS) + $(MAKE) -C t/ unit-tests @@ -39,10 +39,10 @@ Those wishing to help with error message, usage and informational message string translations (localization l10) should see [po/README.md][] (a `po` file is a Portable Object file that holds the translations). -To subscribe to the list, send an email with just "subscribe git" in -the body to majordomo@vger.kernel.org (not the Git list). The mailing +To subscribe to the list, send an email to <git+subscribe@vger.kernel.org> +(see https://subspace.kernel.org/subscribing.html for details). The mailing list archives are available at <https://lore.kernel.org/git/>, -<http://marc.info/?l=git> and other archival sites. +<https://marc.info/?l=git> and other archival sites. Issues which are security relevant should be disclosed privately to the Git Security mailing list <git-security@googlegroups.com>. @@ -1 +1 @@ -Documentation/RelNotes/2.43.0.txt
\ No newline at end of file +Documentation/RelNotes/2.45.0.txt
\ No newline at end of file diff --git a/add-patch.c b/add-patch.c index bfe19876cd..68f525b35c 100644 --- a/add-patch.c +++ b/add-patch.c @@ -12,7 +12,6 @@ #include "strvec.h" #include "pathspec.h" #include "color.h" -#include "diff.h" #include "compat/terminal.h" #include "prompt.h" @@ -1730,14 +1729,6 @@ int run_add_p(struct repository *r, enum add_p_mode mode, if (mode == ADD_P_STASH) s.mode = &patch_mode_stash; else if (mode == ADD_P_RESET) { - /* - * NEEDSWORK: Instead of comparing to the literal "HEAD", - * compare the commit objects instead so that other ways of - * saying the same thing (such as "@") are also handled - * appropriately. - * - * This applies to the cases below too. - */ if (!revision || !strcmp(revision, "HEAD")) s.mode = &patch_mode_reset_head; else @@ -33,52 +33,57 @@ static const char *advise_get_color(enum color_advice ix) return ""; } +enum advice_level { + ADVICE_LEVEL_NONE = 0, + ADVICE_LEVEL_DISABLED, + ADVICE_LEVEL_ENABLED, +}; + static struct { const char *key; - int enabled; + enum advice_level level; } advice_setting[] = { - [ADVICE_ADD_EMBEDDED_REPO] = { "addEmbeddedRepo", 1 }, - [ADVICE_ADD_EMPTY_PATHSPEC] = { "addEmptyPathspec", 1 }, - [ADVICE_ADD_IGNORED_FILE] = { "addIgnoredFile", 1 }, - [ADVICE_AM_WORK_DIR] = { "amWorkDir", 1 }, - [ADVICE_AMBIGUOUS_FETCH_REFSPEC] = { "ambiguousFetchRefspec", 1 }, - [ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] = { "checkoutAmbiguousRemoteBranchName", 1 }, - [ADVICE_COMMIT_BEFORE_MERGE] = { "commitBeforeMerge", 1 }, - [ADVICE_DETACHED_HEAD] = { "detachedHead", 1 }, - [ADVICE_SUGGEST_DETACHING_HEAD] = { "suggestDetachingHead", 1 }, - [ADVICE_DIVERGING] = { "diverging", 1 }, - [ADVICE_FETCH_SHOW_FORCED_UPDATES] = { "fetchShowForcedUpdates", 1 }, - [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated", 1 }, - [ADVICE_IGNORED_HOOK] = { "ignoredHook", 1 }, - [ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity", 1 }, - [ADVICE_NESTED_TAG] = { "nestedTag", 1 }, - [ADVICE_OBJECT_NAME_WARNING] = { "objectNameWarning", 1 }, - [ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists", 1 }, - [ADVICE_PUSH_FETCH_FIRST] = { "pushFetchFirst", 1 }, - [ADVICE_PUSH_NEEDS_FORCE] = { "pushNeedsForce", 1 }, - [ADVICE_PUSH_REF_NEEDS_UPDATE] = { "pushRefNeedsUpdate", 1 }, - - /* make this an alias for backward compatibility */ - [ADVICE_PUSH_UPDATE_REJECTED_ALIAS] = { "pushNonFastForward", 1 }, - - [ADVICE_PUSH_NON_FF_CURRENT] = { "pushNonFFCurrent", 1 }, - [ADVICE_PUSH_NON_FF_MATCHING] = { "pushNonFFMatching", 1 }, - [ADVICE_PUSH_UNQUALIFIED_REF_NAME] = { "pushUnqualifiedRefName", 1 }, - [ADVICE_PUSH_UPDATE_REJECTED] = { "pushUpdateRejected", 1 }, - [ADVICE_RESET_NO_REFRESH_WARNING] = { "resetNoRefresh", 1 }, - [ADVICE_RESOLVE_CONFLICT] = { "resolveConflict", 1 }, - [ADVICE_RM_HINTS] = { "rmHints", 1 }, - [ADVICE_SEQUENCER_IN_USE] = { "sequencerInUse", 1 }, - [ADVICE_SET_UPSTREAM_FAILURE] = { "setUpstreamFailure", 1 }, - [ADVICE_SKIPPED_CHERRY_PICKS] = { "skippedCherryPicks", 1 }, - [ADVICE_STATUS_AHEAD_BEHIND_WARNING] = { "statusAheadBehindWarning", 1 }, - [ADVICE_STATUS_HINTS] = { "statusHints", 1 }, - [ADVICE_STATUS_U_OPTION] = { "statusUoption", 1 }, - [ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE] = { "submoduleAlternateErrorStrategyDie", 1 }, - [ADVICE_SUBMODULES_NOT_UPDATED] = { "submodulesNotUpdated", 1 }, - [ADVICE_UPDATE_SPARSE_PATH] = { "updateSparsePath", 1 }, - [ADVICE_WAITING_FOR_EDITOR] = { "waitingForEditor", 1 }, - [ADVICE_WORKTREE_ADD_ORPHAN] = { "worktreeAddOrphan", 1 }, + [ADVICE_ADD_EMBEDDED_REPO] = { "addEmbeddedRepo" }, + [ADVICE_ADD_EMPTY_PATHSPEC] = { "addEmptyPathspec" }, + [ADVICE_ADD_IGNORED_FILE] = { "addIgnoredFile" }, + [ADVICE_AMBIGUOUS_FETCH_REFSPEC] = { "ambiguousFetchRefspec" }, + [ADVICE_AM_WORK_DIR] = { "amWorkDir" }, + [ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] = { "checkoutAmbiguousRemoteBranchName" }, + [ADVICE_COMMIT_BEFORE_MERGE] = { "commitBeforeMerge" }, + [ADVICE_DETACHED_HEAD] = { "detachedHead" }, + [ADVICE_DIVERGING] = { "diverging" }, + [ADVICE_FETCH_SHOW_FORCED_UPDATES] = { "fetchShowForcedUpdates" }, + [ADVICE_FORCE_DELETE_BRANCH] = { "forceDeleteBranch" }, + [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated" }, + [ADVICE_IGNORED_HOOK] = { "ignoredHook" }, + [ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity" }, + [ADVICE_NESTED_TAG] = { "nestedTag" }, + [ADVICE_OBJECT_NAME_WARNING] = { "objectNameWarning" }, + [ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists" }, + [ADVICE_PUSH_FETCH_FIRST] = { "pushFetchFirst" }, + [ADVICE_PUSH_NEEDS_FORCE] = { "pushNeedsForce" }, + [ADVICE_PUSH_NON_FF_CURRENT] = { "pushNonFFCurrent" }, + [ADVICE_PUSH_NON_FF_MATCHING] = { "pushNonFFMatching" }, + [ADVICE_PUSH_REF_NEEDS_UPDATE] = { "pushRefNeedsUpdate" }, + [ADVICE_PUSH_UNQUALIFIED_REF_NAME] = { "pushUnqualifiedRefName" }, + [ADVICE_PUSH_UPDATE_REJECTED] = { "pushUpdateRejected" }, + [ADVICE_PUSH_UPDATE_REJECTED_ALIAS] = { "pushNonFastForward" }, /* backwards compatibility */ + [ADVICE_RESET_NO_REFRESH_WARNING] = { "resetNoRefresh" }, + [ADVICE_RESOLVE_CONFLICT] = { "resolveConflict" }, + [ADVICE_RM_HINTS] = { "rmHints" }, + [ADVICE_SEQUENCER_IN_USE] = { "sequencerInUse" }, + [ADVICE_SET_UPSTREAM_FAILURE] = { "setUpstreamFailure" }, + [ADVICE_SKIPPED_CHERRY_PICKS] = { "skippedCherryPicks" }, + [ADVICE_STATUS_AHEAD_BEHIND_WARNING] = { "statusAheadBehindWarning" }, + [ADVICE_STATUS_HINTS] = { "statusHints" }, + [ADVICE_STATUS_U_OPTION] = { "statusUoption" }, + [ADVICE_SUBMODULES_NOT_UPDATED] = { "submodulesNotUpdated" }, + [ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE] = { "submoduleAlternateErrorStrategyDie" }, + [ADVICE_SUBMODULE_MERGE_CONFLICT] = { "submoduleMergeConflict" }, + [ADVICE_SUGGEST_DETACHING_HEAD] = { "suggestDetachingHead" }, + [ADVICE_UPDATE_SPARSE_PATH] = { "updateSparsePath" }, + [ADVICE_WAITING_FOR_EDITOR] = { "waitingForEditor" }, + [ADVICE_WORKTREE_ADD_ORPHAN] = { "worktreeAddOrphan" }, }; static const char turn_off_instructions[] = @@ -118,13 +123,13 @@ void advise(const char *advice, ...) int advice_enabled(enum advice_type type) { - switch(type) { - case ADVICE_PUSH_UPDATE_REJECTED: - return advice_setting[ADVICE_PUSH_UPDATE_REJECTED].enabled && - advice_setting[ADVICE_PUSH_UPDATE_REJECTED_ALIAS].enabled; - default: - return advice_setting[type].enabled; - } + int enabled = advice_setting[type].level != ADVICE_LEVEL_DISABLED; + + if (type == ADVICE_PUSH_UPDATE_REJECTED) + return enabled && + advice_enabled(ADVICE_PUSH_UPDATE_REJECTED_ALIAS); + + return enabled; } void advise_if_enabled(enum advice_type type, const char *advice, ...) @@ -135,7 +140,8 @@ void advise_if_enabled(enum advice_type type, const char *advice, ...) return; va_start(params, advice); - vadvise(advice, 1, advice_setting[type].key, params); + vadvise(advice, !advice_setting[type].level, advice_setting[type].key, + params); va_end(params); } @@ -164,7 +170,9 @@ int git_default_advice_config(const char *var, const char *value) for (i = 0; i < ARRAY_SIZE(advice_setting); i++) { if (strcasecmp(k, advice_setting[i].key)) continue; - advice_setting[i].enabled = git_config_bool(var, value); + advice_setting[i].level = git_config_bool(var, value) + ? ADVICE_LEVEL_ENABLED + : ADVICE_LEVEL_DISABLED; return 0; } @@ -10,18 +10,18 @@ struct string_list; * Add the new config variable to Documentation/config/advice.txt. * Call advise_if_enabled to print your advice. */ - enum advice_type { +enum advice_type { ADVICE_ADD_EMBEDDED_REPO, ADVICE_ADD_EMPTY_PATHSPEC, ADVICE_ADD_IGNORED_FILE, - ADVICE_AM_WORK_DIR, ADVICE_AMBIGUOUS_FETCH_REFSPEC, + ADVICE_AM_WORK_DIR, ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME, ADVICE_COMMIT_BEFORE_MERGE, ADVICE_DETACHED_HEAD, ADVICE_DIVERGING, - ADVICE_SUGGEST_DETACHING_HEAD, ADVICE_FETCH_SHOW_FORCED_UPDATES, + ADVICE_FORCE_DELETE_BRANCH, ADVICE_GRAFT_FILE_DEPRECATED, ADVICE_IGNORED_HOOK, ADVICE_IMPLICIT_IDENTITY, @@ -32,23 +32,25 @@ struct string_list; ADVICE_PUSH_NEEDS_FORCE, ADVICE_PUSH_NON_FF_CURRENT, ADVICE_PUSH_NON_FF_MATCHING, + ADVICE_PUSH_REF_NEEDS_UPDATE, ADVICE_PUSH_UNQUALIFIED_REF_NAME, - ADVICE_PUSH_UPDATE_REJECTED_ALIAS, ADVICE_PUSH_UPDATE_REJECTED, - ADVICE_PUSH_REF_NEEDS_UPDATE, + ADVICE_PUSH_UPDATE_REJECTED_ALIAS, ADVICE_RESET_NO_REFRESH_WARNING, ADVICE_RESOLVE_CONFLICT, ADVICE_RM_HINTS, ADVICE_SEQUENCER_IN_USE, ADVICE_SET_UPSTREAM_FAILURE, + ADVICE_SKIPPED_CHERRY_PICKS, ADVICE_STATUS_AHEAD_BEHIND_WARNING, ADVICE_STATUS_HINTS, ADVICE_STATUS_U_OPTION, - ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE, ADVICE_SUBMODULES_NOT_UPDATED, + ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE, + ADVICE_SUBMODULE_MERGE_CONFLICT, + ADVICE_SUGGEST_DETACHING_HEAD, ADVICE_UPDATE_SPARSE_PATH, ADVICE_WAITING_FOR_EDITOR, - ADVICE_SKIPPED_CHERRY_PICKS, ADVICE_WORKTREE_ADD_ORPHAN, }; @@ -12,7 +12,6 @@ #include "base85.h" #include "config.h" #include "object-store-ll.h" -#include "blob.h" #include "delta.h" #include "diff.h" #include "dir.h" @@ -78,7 +77,8 @@ static int parse_whitespace_option(struct apply_state *state, const char *option return 0; } /* - * Please update $__git_whitespacelist in git-completion.bash + * Please update $__git_whitespacelist in git-completion.bash, + * Documentation/git-apply.txt, and Documentation/git-am.txt * when you add new options. */ return error(_("unrecognized whitespace option '%s'"), option); @@ -2220,7 +2220,8 @@ static void reverse_patches(struct patch *p) struct fragment *frag = p->fragments; SWAP(p->new_name, p->old_name); - SWAP(p->new_mode, p->old_mode); + if (p->new_mode) + SWAP(p->new_mode, p->old_mode); SWAP(p->is_new, p->is_delete); SWAP(p->lines_added, p->lines_deleted); SWAP(p->old_oid_prefix, p->new_oid_prefix); @@ -3778,8 +3779,17 @@ static int check_preimage(struct apply_state *state, return error_errno("%s", old_name); } - if (!state->cached && !previous) - st_mode = ce_mode_from_stat(*ce, st->st_mode); + if (!state->cached && !previous) { + if (*ce && !(*ce)->ce_mode) + BUG("ce_mode == 0 for path '%s'", old_name); + + if (trust_executable_bit) + st_mode = ce_mode_from_stat(*ce, st->st_mode); + else if (*ce) + st_mode = (*ce)->ce_mode; + else + st_mode = patch->old_mode; + } if (patch->is_new < 0) patch->is_new = 0; diff --git a/archive-tar.c b/archive-tar.c index 0726996839..8ae30125f8 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -9,6 +9,7 @@ #include "tar.h" #include "archive.h" #include "object-store-ll.h" +#include "strbuf.h" #include "streaming.h" #include "run-command.h" #include "write-or-die.h" @@ -364,7 +365,7 @@ static struct archiver *find_tar_filter(const char *name, size_t len) int i; for (i = 0; i < nr_tar_filters; i++) { struct archiver *ar = tar_filters[i]; - if (!strncmp(ar->name, name, len) && !ar->name[len]) + if (!xstrncmpz(ar->name, name, len)) return ar; } return NULL; diff --git a/archive-zip.c b/archive-zip.c index 7229e3e454..fd1d3f816d 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -10,6 +10,7 @@ #include "streaming.h" #include "utf8.h" #include "object-store-ll.h" +#include "strbuf.h" #include "userdiff.h" #include "write-or-die.h" #include "xdiff-interface.h" @@ -5,6 +5,7 @@ #include "environment.h" #include "gettext.h" #include "hex.h" +#include "object-name.h" #include "path.h" #include "pretty.h" #include "setup.h" @@ -17,7 +18,6 @@ #include "archive.h" #include "parse-options.h" #include "unpack-trees.h" -#include "dir.h" #include "quote.h" static char const * const archive_usage[] = { @@ -685,6 +685,8 @@ static int parse_archive_args(int argc, const char **argv, base = ""; if (list) { + if (argc) + die(_("extra command line parameter '%s'"), *argv); for (i = 0; i < nr_archivers; i++) if (!is_remote || archivers[i]->flags & ARCHIVER_REMOTE) printf("%s\n", archivers[i]->name); @@ -1,7 +1,6 @@ #ifndef ARCHIVE_H #define ARCHIVE_H -#include "object-name.h" #include "pathspec.h" #include "string-list.h" @@ -17,6 +17,7 @@ #include "utf8.h" #include "quote.h" #include "read-cache-ll.h" +#include "refs.h" #include "revision.h" #include "object-store-ll.h" #include "setup.h" @@ -183,6 +184,15 @@ static void all_attrs_init(struct attr_hashmap *map, struct attr_check *check) } } +/* + * Atribute name cannot begin with "builtin_" which + * is a reserved namespace for built in attributes values. + */ +static int attr_name_reserved(const char *name) +{ + return starts_with(name, "builtin_"); +} + static int attr_name_valid(const char *name, size_t namelen) { /* @@ -315,7 +325,7 @@ static const char *parse_attr(const char *src, int lineno, const char *cp, cp++; len--; } - if (!attr_name_valid(cp, len)) { + if (!attr_name_valid(cp, len) || attr_name_reserved(cp)) { report_invalid_attr(cp, len, src, lineno); return NULL; } @@ -379,7 +389,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, name += strlen(ATTRIBUTE_MACRO_PREFIX); name += strspn(name, blank); namelen = strcspn(name, blank); - if (!attr_name_valid(name, namelen)) { + if (!attr_name_valid(name, namelen) || attr_name_reserved(name)) { report_invalid_attr(name, namelen, src, lineno); goto fail_return; } @@ -1240,6 +1250,85 @@ static struct object_id *default_attr_source(void) return &attr_source; } +static const char *interned_mode_string(unsigned int mode) +{ + static struct { + unsigned int val; + char str[7]; + } mode_string[] = { + { .val = 0040000 }, + { .val = 0100644 }, + { .val = 0100755 }, + { .val = 0120000 }, + { .val = 0160000 }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(mode_string); i++) { + if (mode_string[i].val != mode) + continue; + if (!*mode_string[i].str) + snprintf(mode_string[i].str, sizeof(mode_string[i].str), + "%06o", mode); + return mode_string[i].str; + } + BUG("Unsupported mode 0%o", mode); +} + +static const char *builtin_object_mode_attr(struct index_state *istate, const char *path) +{ + unsigned int mode; + + if (direction == GIT_ATTR_CHECKIN) { + struct object_id oid; + struct stat st; + if (lstat(path, &st)) + die_errno(_("unable to stat '%s'"), path); + mode = canon_mode(st.st_mode); + if (S_ISDIR(mode)) { + /* + *`path` is either a directory or it is a submodule, + * in which case it is already indexed as submodule + * or it does not exist in the index yet and we need to + * check if we can resolve to a ref. + */ + int pos = index_name_pos(istate, path, strlen(path)); + if (pos >= 0) { + if (S_ISGITLINK(istate->cache[pos]->ce_mode)) + mode = istate->cache[pos]->ce_mode; + } else if (resolve_gitlink_ref(path, "HEAD", &oid) == 0) { + mode = S_IFGITLINK; + } + } + } else { + /* + * For GIT_ATTR_CHECKOUT and GIT_ATTR_INDEX we only check + * for mode in the index. + */ + int pos = index_name_pos(istate, path, strlen(path)); + if (pos >= 0) + mode = istate->cache[pos]->ce_mode; + else + return ATTR__UNSET; + } + + return interned_mode_string(mode); +} + + +static const char *compute_builtin_attr(struct index_state *istate, + const char *path, + const struct git_attr *attr) { + static const struct git_attr *object_mode_attr; + + if (!object_mode_attr) + object_mode_attr = git_attr("builtin_objectmode"); + + if (attr == object_mode_attr) + return builtin_object_mode_attr(istate, path); + return ATTR__UNSET; +} + void git_check_attr(struct index_state *istate, const char *path, struct attr_check *check) @@ -1253,7 +1342,7 @@ void git_check_attr(struct index_state *istate, unsigned int n = check->items[i].attr->attr_nr; const char *value = check->all_attrs[n].value; if (value == ATTR__UNKNOWN) - value = ATTR__UNSET; + value = compute_builtin_attr(istate, path, check->all_attrs[n].attr); check->items[i].value = value; } } @@ -9,7 +9,6 @@ #include "refs.h" #include "list-objects.h" #include "quote.h" -#include "hash-lookup.h" #include "run-command.h" #include "log-tree.h" #include "bisect.h" @@ -159,6 +158,9 @@ static void show_list(const char *debug, int counted, int nr, const char *subject_start; int subject_len; + if (!buf) + die(_("unable to read %s"), oid_to_hex(&commit->object.oid)); + fprintf(stderr, "%c%c%c ", (commit_flags & TREESAME) ? ' ' : 'T', (commit_flags & UNINTERESTING) ? 'U' : ' ', @@ -471,7 +473,6 @@ static int read_bisect_refs(void) } static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES") -static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV") static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK") static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN") static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START") @@ -707,26 +708,10 @@ static enum bisect_error error_if_skipped_commits(struct commit_list *tried, static int is_expected_rev(const struct object_id *oid) { - const char *filename = git_path_bisect_expected_rev(); - struct stat st; - struct strbuf str = STRBUF_INIT; - FILE *fp; - int res = 0; - - if (stat(filename, &st) || !S_ISREG(st.st_mode)) - return 0; - - fp = fopen_or_warn(filename, "r"); - if (!fp) + struct object_id expected_oid; + if (read_ref("BISECT_EXPECTED_REV", &expected_oid)) return 0; - - if (strbuf_getline_lf(&str, fp) != EOF) - res = !strcmp(str.buf, oid_to_hex(oid)); - - strbuf_release(&str); - fclose(fp); - - return res; + return oideq(oid, &expected_oid); } enum bisect_error bisect_checkout(const struct object_id *bisect_rev, @@ -1185,10 +1170,10 @@ int bisect_clean_state(void) struct string_list refs_for_removal = STRING_LIST_INIT_NODUP; for_each_ref_in("refs/bisect", mark_for_removal, (void *) &refs_for_removal); string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD")); + string_list_append(&refs_for_removal, xstrdup("BISECT_EXPECTED_REV")); result = delete_refs("bisect: remove", &refs_for_removal, REF_NO_DEREF); refs_for_removal.strdup_strings = 1; string_list_clear(&refs_for_removal, 0); - unlink_or_warn(git_path_bisect_expected_rev()); unlink_or_warn(git_path_bisect_ancestors_ok()); unlink_or_warn(git_path_bisect_log()); unlink_or_warn(git_path_bisect_names()); @@ -3,6 +3,7 @@ #include "object-store-ll.h" #include "cache-tree.h" #include "mergesort.h" +#include "commit.h" #include "convert.h" #include "diff.h" #include "diffcore.h" @@ -10,6 +11,7 @@ #include "hex.h" #include "path.h" #include "read-cache.h" +#include "revision.h" #include "setup.h" #include "tag.h" #include "trace2.h" @@ -1,12 +1,9 @@ #ifndef BLAME_H #define BLAME_H -#include "commit.h" #include "oidset.h" #include "xdiff-interface.h" -#include "revision.h" #include "prio-queue.h" -#include "diff.h" #define PICKAXE_BLAME_MOVE 01 #define PICKAXE_BLAME_COPY 02 @@ -1,6 +1,5 @@ #include "git-compat-util.h" #include "blob.h" -#include "repository.h" #include "alloc.h" const char *blob_type = "blob"; @@ -2,7 +2,6 @@ #include "bloom.h" #include "diff.h" #include "diffcore.h" -#include "revision.h" #include "hashmap.h" #include "commit-graph.h" #include "commit.h" @@ -420,9 +420,9 @@ static void prepare_checked_out_branches(void) wt_status_state_free_buffers(&state); if (wt_status_check_bisect(wt, &state) && - state.branch) { + state.bisecting_from) { struct strbuf ref = STRBUF_INIT; - strbuf_addf(&ref, "refs/heads/%s", state.branch); + strbuf_addf(&ref, "refs/heads/%s", state.bisecting_from); old = strmap_put(¤t_checked_out_branches, ref.buf, xstrdup(wt->path)); @@ -817,8 +817,9 @@ void remove_merge_branch_state(struct repository *r) unlink(git_path_merge_rr(r)); unlink(git_path_merge_msg(r)); unlink(git_path_merge_mode(r)); - unlink(git_path_auto_merge(r)); - save_autostash(git_path_merge_autostash(r)); + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE", + NULL, REF_NO_DEREF); + save_autostash_ref(r, "MERGE_AUTOSTASH"); } void remove_branch_state(struct repository *r, int verbose) @@ -211,6 +211,7 @@ int cmd_remote(int argc, const char **argv, const char *prefix); int cmd_remote_ext(int argc, const char **argv, const char *prefix); int cmd_remote_fd(int argc, const char **argv, const char *prefix); int cmd_repack(int argc, const char **argv, const char *prefix); +int cmd_replay(int argc, const char **argv, const char *prefix); int cmd_rerere(int argc, const char **argv, const char *prefix); int cmd_reset(int argc, const char **argv, const char *prefix); int cmd_restore(int argc, const char **argv, const char *prefix); diff --git a/builtin/add.c b/builtin/add.c index 5126d2ede3..ada7719561 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -12,14 +12,11 @@ #include "dir.h" #include "gettext.h" #include "pathspec.h" -#include "exec-cmd.h" -#include "cache-tree.h" #include "run-command.h" #include "parse-options.h" #include "path.h" #include "preload-index.h" #include "diff.h" -#include "diffcore.h" #include "read-cache.h" #include "repository.h" #include "revision.h" @@ -424,7 +421,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) * Check the "pathspec '%s' did not match any files" block * below before enabling new magic. */ - parse_pathspec(&pathspec, PATHSPEC_ATTR, + parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_FULL | PATHSPEC_SYMLINK_LEADING_PATH, prefix, argv); @@ -433,7 +430,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (pathspec.nr) die(_("'%s' and pathspec arguments cannot be used together"), "--pathspec-from-file"); - parse_pathspec_file(&pathspec, PATHSPEC_ATTR, + parse_pathspec_file(&pathspec, 0, PATHSPEC_PREFER_FULL | PATHSPEC_SYMLINK_LEADING_PATH, prefix, pathspec_from_file, pathspec_file_nul); @@ -504,7 +501,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) PATHSPEC_LITERAL | PATHSPEC_GLOB | PATHSPEC_ICASE | - PATHSPEC_EXCLUDE); + PATHSPEC_EXCLUDE | + PATHSPEC_ATTR); for (i = 0; i < pathspec.nr; i++) { const char *path = pathspec.items[i].match; diff --git a/builtin/am.c b/builtin/am.c index 9f084d58bc..d1990d7edc 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -10,7 +10,6 @@ #include "config.h" #include "editor.h" #include "environment.h" -#include "exec-cmd.h" #include "gettext.h" #include "hex.h" #include "parse-options.h" @@ -24,7 +23,6 @@ #include "refs.h" #include "commit.h" #include "diff.h" -#include "diffcore.h" #include "unpack-trees.h" #include "branch.h" #include "object-name.h" @@ -35,11 +33,9 @@ #include "log-tree.h" #include "notes-utils.h" #include "rerere.h" -#include "prompt.h" #include "mailinfo.h" #include "apply.h" #include "string-list.h" -#include "packfile.h" #include "pager.h" #include "path.h" #include "repository.h" diff --git a/builtin/apply.c b/builtin/apply.c index c18b7ea5d3..861a01910c 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -1,6 +1,5 @@ #include "builtin.h" #include "gettext.h" -#include "parse-options.h" #include "repository.h" #include "apply.h" diff --git a/builtin/archive.c b/builtin/archive.c index 90761fdfee..15ee1ec7bb 100644 --- a/builtin/archive.c +++ b/builtin/archive.c @@ -9,7 +9,6 @@ #include "parse-options.h" #include "pkt-line.h" #include "repository.h" -#include "sideband.h" static void create_output_file(const char *output_file) { diff --git a/builtin/bisect.c b/builtin/bisect.c index 35938b05fd..f69c3f7e43 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -7,7 +7,6 @@ #include "parse-options.h" #include "bisect.h" #include "refs.h" -#include "dir.h" #include "strvec.h" #include "run-command.h" #include "oid-array.h" @@ -17,7 +16,6 @@ #include "revision.h" static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS") -static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV") static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK") static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START") static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG") @@ -233,11 +231,10 @@ static int bisect_reset(const char *commit) struct strbuf branch = STRBUF_INIT; if (!commit) { - if (strbuf_read_file(&branch, git_path_bisect_start(), 0) < 1) { + if (!strbuf_read_file(&branch, git_path_bisect_start(), 0)) printf(_("We are not bisecting.\n")); - return 0; - } - strbuf_rtrim(&branch); + else + strbuf_rtrim(&branch); } else { struct object_id oid; @@ -246,7 +243,7 @@ static int bisect_reset(const char *commit) strbuf_addstr(&branch, commit); } - if (!ref_exists("BISECT_HEAD")) { + if (branch.len && !ref_exists("BISECT_HEAD")) { struct child_process cmd = CHILD_PROCESS_INIT; cmd.git_cmd = 1; @@ -921,7 +918,6 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc, const char *state; int i, verify_expected = 1; struct object_id oid, expected; - struct strbuf buf = STRBUF_INIT; struct oid_array revs = OID_ARRAY_INIT; if (!argc) @@ -976,10 +972,8 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc, oid_array_append(&revs, &commit->object.oid); } - if (strbuf_read_file(&buf, git_path_bisect_expected_rev(), 0) < the_hash_algo->hexsz || - get_oid_hex(buf.buf, &expected) < 0) + if (read_ref("BISECT_EXPECTED_REV", &expected)) verify_expected = 0; /* Ignore invalid file contents */ - strbuf_release(&buf); for (i = 0; i < revs.nr; i++) { if (bisect_write(state, oid_to_hex(&revs.oid[i]), terms, 0)) { @@ -988,7 +982,7 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc, } if (verify_expected && !oideq(&revs.oid[i], &expected)) { unlink_or_warn(git_path_bisect_ancestors_ok()); - unlink_or_warn(git_path_bisect_expected_rev()); + delete_ref(NULL, "BISECT_EXPECTED_REV", NULL, REF_NO_DEREF); verify_expected = 0; } } diff --git a/builtin/blame.c b/builtin/blame.c index 9c987d6567..db1f56de61 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -25,7 +25,6 @@ #include "userdiff.h" #include "line-range.h" #include "line-log.h" -#include "dir.h" #include "progress.h" #include "object-name.h" #include "object-store-ll.h" @@ -748,6 +747,8 @@ static int git_blame_config(const char *var, const char *value, } if (!strcmp(var, "blame.coloring")) { + if (!value) + return config_error_nonbool(var); if (!strcmp(value, "repeatedLines")) { coloring_mode |= OUTPUT_COLOR_LINE; } else if (!strcmp(value, "highlightRecent")) { diff --git a/builtin/branch.c b/builtin/branch.c index e7ee9bd0f1..cfb63cce5f 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -17,16 +17,14 @@ #include "remote.h" #include "parse-options.h" #include "branch.h" -#include "diff.h" #include "path.h" -#include "revision.h" #include "string-list.h" #include "column.h" #include "utf8.h" -#include "wt-status.h" #include "ref-filter.h" #include "worktree.h" #include "help.h" +#include "advice.h" #include "commit-reach.h" static const char * const builtin_branch_usage[] = { @@ -45,7 +43,6 @@ static const char *head; static struct object_id head_oid; static int recurse_submodules = 0; static int submodule_propagate_branches = 0; -static int omit_empty = 0; static int branch_use_color = -1; static char branch_colors[][COLOR_MAXLEN] = { @@ -194,9 +191,10 @@ static int check_branch_commit(const char *branchname, const char *refname, return -1; } if (!force && !branch_merged(kinds, branchname, rev, head_rev)) { - error(_("the branch '%s' is not fully merged.\n" - "If you are sure you want to delete it, " - "run 'git branch -D %s'"), branchname, branchname); + error(_("the branch '%s' is not fully merged"), branchname); + advise_if_enabled(ADVICE_FORCE_DELETE_BRANCH, + _("If you are sure you want to delete it, " + "run 'git branch -D %s'"), branchname); return -1; } return 0; @@ -438,8 +436,6 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin { int i; struct ref_array array; - struct strbuf out = STRBUF_INIT; - struct strbuf err = STRBUF_INIT; int maxwidth = 0; const char *remote_prefix = ""; char *to_free = NULL; @@ -469,24 +465,27 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin filter_ahead_behind(the_repository, format, &array); ref_array_sort(sorting, &array); - for (i = 0; i < array.nr; i++) { - strbuf_reset(&err); - strbuf_reset(&out); - if (format_ref_array_item(array.items[i], format, &out, &err)) - die("%s", err.buf); - if (column_active(colopts)) { - assert(!filter->verbose && "--column and --verbose are incompatible"); - /* format to a string_list to let print_columns() do its job */ + if (column_active(colopts)) { + struct strbuf out = STRBUF_INIT, err = STRBUF_INIT; + + assert(!filter->verbose && "--column and --verbose are incompatible"); + + for (i = 0; i < array.nr; i++) { + strbuf_reset(&err); + strbuf_reset(&out); + if (format_ref_array_item(array.items[i], format, &out, &err)) + die("%s", err.buf); + + /* format to a string_list to let print_columns() do its job */ string_list_append(output, out.buf); - } else { - fwrite(out.buf, 1, out.len, stdout); - if (out.len || !omit_empty) - putchar('\n'); } + + strbuf_release(&err); + strbuf_release(&out); + } else { + print_formatted_ref_array(&array, format); } - strbuf_release(&err); - strbuf_release(&out); ref_array_clear(&array); free(to_free); } @@ -737,7 +736,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2), OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1), OPT_BIT('M', NULL, &rename, N_("move/rename a branch, even if target exists"), 2), - OPT_BOOL(0, "omit-empty", &omit_empty, + OPT_BOOL(0, "omit-empty", &format.array_opts.omit_empty, N_("do not output a newline after empty formatted refs")), OPT_BIT('c', "copy", ©, N_("copy a branch and its reflog"), 1), OPT_BIT('C', NULL, ©, N_("copy a branch, even if target exists"), 2), @@ -767,7 +766,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(builtin_branch_usage, options); + /* + * Try to set sort keys from config. If config does not set any, + * fall back on default (refname) sorting. + */ git_config(git_branch_config, &sorting_options); + if (!sorting_options.nr) + string_list_append(&sorting_options, "refname"); track = git_branch_track; diff --git a/builtin/cat-file.c b/builtin/cat-file.c index ea8ad601ec..bbf851138e 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -15,7 +15,6 @@ #include "parse-options.h" #include "userdiff.h" #include "streaming.h" -#include "tree-walk.h" #include "oid-array.h" #include "packfile.h" #include "object-file.h" @@ -222,6 +221,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, &type, &size); const char *target; + + if (!buffer) + die(_("unable to read %s"), oid_to_hex(&oid)); + if (!skip_prefix(buffer, "object ", &target) || get_oid_hex(target, &blob_oid)) die("%s not a valid tag", oid_to_hex(&oid)); @@ -417,6 +420,8 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d contents = repo_read_object_file(the_repository, oid, &type, &size); + if (!contents) + die("object %s disappeared", oid_to_hex(oid)); if (use_mailmap) { size_t s = size; @@ -424,8 +429,6 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d size = cast_size_t_to_ulong(s); } - if (!contents) - die("object %s disappeared", oid_to_hex(oid)); if (type != data->type) die("object %s changed type!?", oid_to_hex(oid)); if (data->info.sizep && size != data->size && !use_mailmap) @@ -482,6 +485,8 @@ static void batch_object_write(const char *obj_name, buf = repo_read_object_file(the_repository, &data->oid, &data->type, &data->size); + if (!buf) + die(_("unable to read %s"), oid_to_hex(&data->oid)); buf = replace_idents_using_mailmap(buf, &s); data->size = cast_size_t_to_ulong(s); diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index 3b68b47615..2e086a204d 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -7,7 +7,6 @@ #define USE_THE_INDEX_VARIABLE #include "builtin.h" #include "config.h" -#include "dir.h" #include "gettext.h" #include "lockfile.h" #include "quote.h" diff --git a/builtin/checkout.c b/builtin/checkout.c index f02434bc15..067c251933 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1,7 +1,6 @@ #define USE_THE_INDEX_VARIABLE #include "builtin.h" #include "advice.h" -#include "blob.h" #include "branch.h" #include "cache-tree.h" #include "checkout.h" @@ -27,10 +26,8 @@ #include "remote.h" #include "resolve-undo.h" #include "revision.h" -#include "run-command.h" #include "setup.h" #include "submodule.h" -#include "submodule-config.h" #include "symlinks.h" #include "trace2.h" #include "tree.h" @@ -1202,6 +1199,8 @@ static int git_checkout_config(const char *var, const char *value, struct checkout_opts *opts = cb; if (!strcmp(var, "diff.ignoresubmodules")) { + if (!value) + return config_error_nonbool(var); handle_ignore_submodules_arg(&opts->diff_options, value); return 0; } @@ -1225,7 +1224,9 @@ static void setup_new_branch_info_and_source_tree( struct tree **source_tree = &opts->source_tree; struct object_id branch_rev; - new_branch_info->name = xstrdup(arg); + /* treat '@' as a shortcut for 'HEAD' */ + new_branch_info->name = !strcmp(arg, "@") ? xstrdup("HEAD") : + xstrdup(arg); setup_branch_path(new_branch_info); if (!check_refname_format(new_branch_info->path, 0) && @@ -1516,6 +1517,26 @@ static void die_if_some_operation_in_progress(void) wt_status_state_free_buffers(&state); } +/* + * die if attempting to checkout an existing branch that is in use + * in another worktree, unless ignore-other-wortrees option is given. + * The check is bypassed when the branch is already the current one, + * as it will not make things any worse. + */ +static void die_if_switching_to_a_branch_in_use(struct checkout_opts *opts, + const char *full_ref) +{ + int flags; + char *head_ref; + + if (opts->ignore_other_worktrees) + return; + head_ref = resolve_refdup("HEAD", 0, NULL, &flags); + if (head_ref && (!(flags & REF_ISSYMREF) || strcmp(head_ref, full_ref))) + die_if_checked_out(full_ref, 1); + free(head_ref); +} + static int checkout_branch(struct checkout_opts *opts, struct branch_info *new_branch_info) { @@ -1576,14 +1597,15 @@ static int checkout_branch(struct checkout_opts *opts, if (!opts->can_switch_when_in_progress) die_if_some_operation_in_progress(); - if (new_branch_info->path && !opts->force_detach && !opts->new_branch && - !opts->ignore_other_worktrees) { - int flag; - char *head_ref = resolve_refdup("HEAD", 0, NULL, &flag); - if (head_ref && - (!(flag & REF_ISSYMREF) || strcmp(head_ref, new_branch_info->path))) - die_if_checked_out(new_branch_info->path, 1); - free(head_ref); + /* "git checkout <branch>" */ + if (new_branch_info->path && !opts->force_detach && !opts->new_branch) + die_if_switching_to_a_branch_in_use(opts, new_branch_info->path); + + /* "git checkout -B <branch>" */ + if (opts->new_branch_force) { + char *full_ref = xstrfmt("refs/heads/%s", opts->new_branch); + die_if_switching_to_a_branch_in_use(opts, full_ref); + free(full_ref); } if (!new_branch_info->commit && opts->new_branch) { @@ -1627,7 +1649,7 @@ static struct option *add_common_switch_branch_options( parse_opt_tracking_mode), OPT__FORCE(&opts->force, N_("force checkout (throw away local modifications)"), PARSE_OPT_NOCOMPLETE), - OPT_STRING(0, "orphan", &opts->new_orphan_branch, N_("new-branch"), N_("new unparented branch")), + OPT_STRING(0, "orphan", &opts->new_orphan_branch, N_("new-branch"), N_("new unborn branch")), OPT_BOOL_F(0, "overwrite-ignore", &opts->overwrite_ignore, N_("update ignored files (default)"), PARSE_OPT_NOCOMPLETE), diff --git a/builtin/clean.c b/builtin/clean.c index 49c224e626..d90766cad3 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -971,7 +971,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) dir.flags |= DIR_SHOW_OTHER_DIRECTORIES; if (ignored && ignored_only) - die(_("-x and -X cannot be used together")); + die(_("options '%s' and '%s' cannot be used together"), "-x", "-X"); if (!ignored) setup_standard_excludes(&dir); if (ignored_only) diff --git a/builtin/clone.c b/builtin/clone.c index c6357af949..bad1b70ce8 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -19,7 +19,6 @@ #include "hex.h" #include "lockfile.h" #include "parse-options.h" -#include "fetch-pack.h" #include "refs.h" #include "refspec.h" #include "object-file.h" @@ -72,6 +71,7 @@ static char *remote_name = NULL; static char *option_branch = NULL; static struct string_list option_not = STRING_LIST_INIT_NODUP; static const char *real_git_dir; +static const char *ref_format; static char *option_upload_pack = "git-upload-pack"; static int option_verbosity; static int option_progress = -1; @@ -157,6 +157,8 @@ static struct option builtin_clone_options[] = { N_("any cloned submodules will be shallow")), OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), N_("separate git dir from working tree")), + OPT_STRING(0, "ref-format", &ref_format, N_("format"), + N_("specify the reference format to use")), OPT_STRING_LIST('c', "config", &option_config, N_("key=value"), N_("set config inside the new repository")), OPT_STRING_LIST(0, "server-option", &server_options, @@ -791,6 +793,8 @@ static int git_clone_config(const char *k, const char *v, const struct config_context *ctx, void *cb) { if (!strcmp(k, "clone.defaultremotename")) { + if (!v) + return config_error_nonbool(k); free(remote_name); remote_name = xstrdup(v); } @@ -930,6 +934,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) int submodule_progress; int filter_submodules = 0; int hash_algo; + unsigned int ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN; const int do_not_override_repo_unix_permissions = -1; struct transport_ls_refs_options transport_ls_refs_options = @@ -955,6 +960,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (option_single_branch == -1) option_single_branch = deepen ? 1 : 0; + if (ref_format) { + ref_storage_format = ref_storage_format_by_name(ref_format); + if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN) + die(_("unknown ref storage format '%s'"), ref_format); + } + if (option_mirror) option_bare = 1; @@ -965,7 +976,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix) } if (bundle_uri && deepen) - die(_("--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-exclude")); + die(_("options '%s' and '%s' cannot be used together"), + "--bundle-uri", + "--depth/--shallow-since/--shallow-exclude"); repo_name = argv[0]; @@ -1097,8 +1110,15 @@ int cmd_clone(int argc, const char **argv, const char *prefix) } } - init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL, - do_not_override_repo_unix_permissions, INIT_DB_QUIET); + /* + * Initialize the repository, but skip initializing the reference + * database. We do not yet know about the object format of the + * repository, and reference backends may persist that information into + * their on-disk data structures. + */ + init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, + ref_storage_format, NULL, + do_not_override_repo_unix_permissions, INIT_DB_QUIET | INIT_DB_SKIP_REFDB); if (real_git_dir) { free((char *)git_dir); @@ -1185,10 +1205,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (option_required_reference.nr || option_optional_reference.nr) setup_reference(); - if (option_sparse_checkout && git_sparse_checkout_init(dir)) - return 1; - - remote = remote_get(remote_name); + remote = remote_get_early(remote_name); refspec_appendf(&remote->fetch, "+%s*:%s*", src_ref_prefix, branch_top.buf); @@ -1266,6 +1283,27 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (transport->smart_options && !deepen && !filter_options.choice) transport->smart_options->check_self_contained_and_connected = 1; + strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD"); + refspec_ref_prefixes(&remote->fetch, + &transport_ls_refs_options.ref_prefixes); + if (option_branch) + expand_ref_prefix(&transport_ls_refs_options.ref_prefixes, + option_branch); + if (!option_no_tags) + strvec_push(&transport_ls_refs_options.ref_prefixes, + "refs/tags/"); + + refs = transport_get_remote_refs(transport, &transport_ls_refs_options); + + /* + * Now that we know what algorithm the remote side is using, let's set + * ours to the same thing. + */ + hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport)); + initialize_repository_version(hash_algo, the_repository->ref_storage_format, 1); + repo_set_hash_algo(the_repository, hash_algo); + create_reference_database(the_repository->ref_storage_format, NULL, 1); + /* * Before fetching from the remote, download and install bundle * data from the --bundle-uri option. @@ -1281,24 +1319,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) bundle_uri); else if (has_heuristic) git_config_set_gently("fetch.bundleuri", bundle_uri); - } - - strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD"); - refspec_ref_prefixes(&remote->fetch, - &transport_ls_refs_options.ref_prefixes); - if (option_branch) - expand_ref_prefix(&transport_ls_refs_options.ref_prefixes, - option_branch); - if (!option_no_tags) - strvec_push(&transport_ls_refs_options.ref_prefixes, - "refs/tags/"); - - refs = transport_get_remote_refs(transport, &transport_ls_refs_options); - - if (refs) - mapped_refs = wanted_peer_refs(refs, &remote->fetch); - - if (!bundle_uri) { + } else { /* * Populate transport->got_remote_bundle_uri and * transport->bundle_uri. We might get nothing. @@ -1319,13 +1340,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix) } } - /* - * Now that we know what algorithm the remote side is using, - * let's set ours to the same thing. - */ - hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport)); - initialize_repository_version(hash_algo, 1); - repo_set_hash_algo(the_repository, hash_algo); + if (refs) + mapped_refs = wanted_peer_refs(refs, &remote->fetch); if (mapped_refs) { /* @@ -1428,6 +1444,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix) dissociate_from_references(); } + if (option_sparse_checkout && git_sparse_checkout_init(dir)) + return 1; + junk_mode = JUNK_LEAVE_REPO; err = checkout(submodule_progress, filter_submodules); diff --git a/builtin/column.c b/builtin/column.c index a83be8bc99..10ff7e0166 100644 --- a/builtin/column.c +++ b/builtin/column.c @@ -45,6 +45,8 @@ int cmd_column(int argc, const char **argv, const char *prefix) memset(&copts, 0, sizeof(copts)); copts.padding = 1; argc = parse_options(argc, argv, prefix, options, builtin_column_usage, 0); + if (copts.padding < 0) + die(_("%s must be non-negative"), "--padding"); if (argc) usage_with_options(builtin_column_usage, options); if (real_command || command) { @@ -56,5 +58,7 @@ int cmd_column(int argc, const char **argv, const char *prefix) string_list_append(&list, sb.buf); print_columns(&list, colopts, &copts); + strbuf_release(&sb); + string_list_clear(&list, 0); return 0; } diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 45d035af60..7102ee90a0 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -1,17 +1,16 @@ #include "builtin.h" #include "commit.h" #include "config.h" -#include "dir.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "lockfile.h" #include "parse-options.h" #include "repository.h" #include "commit-graph.h" #include "object-store-ll.h" #include "progress.h" #include "replace-object.h" +#include "strbuf.h" #include "tag.h" #include "trace2.h" @@ -22,7 +21,7 @@ N_("git commit-graph write [--object-dir <dir>] [--append]\n" \ " [--split[=<strategy>]] [--reachable | --stdin-packs | --stdin-commits]\n" \ " [--changed-paths] [--[no-]max-new-filters <n>] [--[no-]progress]\n" \ - " <split options>") + " <split-options>") static const char * builtin_commit_graph_verify_usage[] = { BUILTIN_COMMIT_GRAPH_VERIFY_USAGE, diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 02625e7176..1bb7819839 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -11,9 +11,6 @@ #include "object-store-ll.h" #include "repository.h" #include "commit.h" -#include "tree.h" -#include "utf8.h" -#include "gpg-interface.h" #include "parse-options.h" static const char * const commit_tree_usage[] = { diff --git a/builtin/commit.c b/builtin/commit.c index 781af2e206..6d1fa71676 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -16,17 +16,12 @@ #include "editor.h" #include "environment.h" #include "diff.h" -#include "diffcore.h" #include "commit.h" #include "gettext.h" #include "revision.h" #include "wt-status.h" #include "run-command.h" -#include "hook.h" -#include "refs.h" -#include "log-tree.h" #include "strbuf.h" -#include "utf8.h" #include "object-name.h" #include "parse-options.h" #include "path.h" @@ -35,9 +30,6 @@ #include "string-list.h" #include "rerere.h" #include "unpack-trees.h" -#include "quote.h" -#include "submodule.h" -#include "gpg-interface.h" #include "column.h" #include "sequencer.h" #include "sparse-index.h" @@ -900,7 +892,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, strbuf_stripspace(&sb, '\0'); if (signoff) - append_signoff(&sb, ignore_non_trailer(sb.buf, sb.len), 0); + append_signoff(&sb, ignored_log_message_bytes(sb.buf, sb.len), 0); if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len) die_errno(_("could not write commit template")); @@ -1885,7 +1877,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) &oid, flags); } - apply_autostash(git_path_merge_autostash(the_repository)); + apply_autostash_ref(the_repository, "MERGE_AUTOSTASH"); cleanup: strbuf_release(&author_ident); diff --git a/builtin/config.c b/builtin/config.c index 11a4d4ef14..b55bfae7d6 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -708,10 +708,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) } if (use_global_config) { - char *user_config, *xdg_config; - - git_global_config(&user_config, &xdg_config); - if (!user_config) + given_config_source.file = git_global_config(); + if (!given_config_source.file) /* * It is unknown if HOME/.gitconfig exists, so * we do not know if we should write to XDG @@ -719,19 +717,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) * is set and points at a sane location. */ die(_("$HOME not set")); - given_config_source.scope = CONFIG_SCOPE_GLOBAL; - - if (access_or_warn(user_config, R_OK, 0) && - xdg_config && !access_or_warn(xdg_config, R_OK, 0)) { - given_config_source.file = xdg_config; - free(user_config); - } else { - given_config_source.file = user_config; - free(xdg_config); - } - } - else if (use_system_config) { + } else if (use_system_config) { given_config_source.file = git_system_config(); given_config_source.scope = CONFIG_SCOPE_SYSTEM; } else if (use_local_config) { @@ -760,7 +747,6 @@ int cmd_config(int argc, const char **argv, const char *prefix) given_config_source.scope = CONFIG_SCOPE_COMMAND; } - if (respect_includes_opt == -1) config_options.respect_includes = !given_config_source.file; else diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c index 43b9d0e5b1..bba96d4ffd 100644 --- a/builtin/credential-cache.c +++ b/builtin/credential-cache.c @@ -7,8 +7,6 @@ #ifndef NO_UNIX_SOCKETS -#include "credential.h" -#include "string-list.h" #include "unix-socket.h" #include "run-command.h" diff --git a/builtin/describe.c b/builtin/describe.c index fb6b0508f3..d6c77a714f 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -7,9 +7,7 @@ #include "lockfile.h" #include "commit.h" #include "tag.h" -#include "blob.h" #include "refs.h" -#include "exec-cmd.h" #include "object-name.h" #include "parse-options.h" #include "read-cache-ll.h" diff --git a/builtin/diff-files.c b/builtin/diff-files.c index f38912cd40..018011f29e 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -11,7 +11,6 @@ #include "preload-index.h" #include "repository.h" #include "revision.h" -#include "submodule.h" static const char diff_files_usage[] = "git diff-files [-q] [-0 | -1 | -2 | -3 | -c | --cc] [<common-diff-options>] [<path>...]" diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 220f341ffa..3e05260ac0 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -7,8 +7,6 @@ #include "repository.h" #include "revision.h" #include "setup.h" -#include "sparse-index.h" -#include "submodule.h" static const char diff_cache_usage[] = "git diff-index [-m] [--cached] [--merge-base] " diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 86be634286..a8e68ce8ef 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -6,7 +6,6 @@ #include "gettext.h" #include "hex.h" #include "log-tree.h" -#include "submodule.h" #include "read-cache-ll.h" #include "repository.h" #include "revision.h" diff --git a/builtin/diff.c b/builtin/diff.c index 55e7d21755..6e196e0c7d 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -10,7 +10,6 @@ #include "lockfile.h" #include "color.h" #include "commit.h" -#include "blob.h" #include "gettext.h" #include "tag.h" #include "diff.h" @@ -21,7 +20,6 @@ #include "revision.h" #include "log-tree.h" #include "setup.h" -#include "submodule.h" #include "oid-array.h" #include "tree.h" diff --git a/builtin/difftool.c b/builtin/difftool.c index 0f5eae9cd4..a3c72b8258 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -18,7 +18,6 @@ #include "copy.h" #include "run-command.h" #include "environment.h" -#include "exec-cmd.h" #include "gettext.h" #include "hex.h" #include "parse-options.h" diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 70aff515ac..4693d18cc9 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -25,7 +25,6 @@ #include "quote.h" #include "remote.h" #include "blob.h" -#include "commit-slab.h" static const char *fast_export_usage[] = { N_("git fast-export [<rev-list-opts>]"), @@ -137,8 +136,7 @@ static int anonymized_entry_cmp(const void *cmp_data UNUSED, a = container_of(eptr, const struct anonymized_entry, hash); if (keydata) { const struct anonymized_entry_key *key = keydata; - int equal = !strncmp(a->orig, key->orig, key->orig_len) && - !a->orig[key->orig_len]; + int equal = !xstrncmpz(a->orig, key->orig, key->orig_len); return !equal; } diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 444f41cf8c..92eda20683 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -2809,8 +2809,7 @@ static void parse_new_tag(const char *arg) enum object_type type; const char *v; - t = mem_pool_alloc(&fi_mem_pool, sizeof(struct tag)); - memset(t, 0, sizeof(struct tag)); + t = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct tag)); t->name = mem_pool_strdup(&fi_mem_pool, arg); if (last_tag) last_tag->next_tag = t; diff --git a/builtin/fetch.c b/builtin/fetch.c index fd134ba74d..0a7a1a3476 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -26,7 +26,6 @@ #include "connected.h" #include "strvec.h" #include "utf8.h" -#include "packfile.h" #include "pager.h" #include "path.h" #include "pkt-line.h" @@ -38,7 +37,6 @@ #include "shallow.h" #include "trace.h" #include "trace2.h" -#include "worktree.h" #include "bundle-uri.h" #define FORCED_UPDATES_DELAY_WARNING_IN_MS (10 * 1000) @@ -102,6 +100,7 @@ static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP; struct fetch_config { enum display_format display_format; + int all; int prune; int prune_tags; int show_forced_updates; @@ -115,6 +114,11 @@ static int git_fetch_config(const char *k, const char *v, { struct fetch_config *fetch_config = cb; + if (!strcmp(k, "fetch.all")) { + fetch_config->all = git_config_bool(k, v); + return 0; + } + if (!strcmp(k, "fetch.prune")) { fetch_config->prune = git_config_bool(k, v); return 0; @@ -444,9 +448,8 @@ static void filter_prefetch_refspec(struct refspec *rs) continue; if (!rs->items[i].dst || (rs->items[i].src && - !strncmp(rs->items[i].src, - ref_namespace[NAMESPACE_TAGS].ref, - strlen(ref_namespace[NAMESPACE_TAGS].ref)))) { + starts_with(rs->items[i].src, + ref_namespace[NAMESPACE_TAGS].ref))) { int j; free(rs->items[i].src); @@ -1651,7 +1654,7 @@ static int do_fetch(struct transport *transport, if (atomic_fetch) { transaction = ref_transaction_begin(&err); if (!transaction) { - retcode = error("%s", err.buf); + retcode = -1; goto cleanup; } } @@ -1711,7 +1714,6 @@ static int do_fetch(struct transport *transport, retcode = ref_transaction_commit(transaction, &err); if (retcode) { - error("%s", err.buf); ref_transaction_free(transaction); transaction = NULL; goto cleanup; @@ -1775,9 +1777,14 @@ static int do_fetch(struct transport *transport, } cleanup: - if (retcode && transaction) { - ref_transaction_abort(transaction, &err); - error("%s", err.buf); + if (retcode) { + if (err.len) { + error("%s", err.buf); + strbuf_reset(&err); + } + if (transaction && ref_transaction_abort(transaction, &err) && + err.len) + error("%s", err.buf); } display_state_release(&display_state); @@ -2128,7 +2135,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) const char *bundle_uri; struct string_list list = STRING_LIST_INIT_DUP; struct remote *remote = NULL; - int all = 0, multiple = 0; + int all = -1, multiple = 0; int result = 0; int prune_tags_ok = 1; int enable_auto_gc = 1; @@ -2333,11 +2340,20 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) fetch_bundle_uri(the_repository, bundle_uri, NULL)) warning(_("failed to fetch bundles from '%s'"), bundle_uri); + if (all < 0) { + /* + * no --[no-]all given; + * only use config option if no remote was explicitly specified + */ + all = (!argc) ? config.all : 0; + } + if (all) { if (argc == 1) die(_("fetch --all does not take a repository argument")); 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 */ diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 350bfa6e81..919282e12a 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -1,13 +1,12 @@ #include "builtin.h" +#include "commit.h" #include "config.h" #include "gettext.h" -#include "refs.h" #include "object.h" #include "parse-options.h" #include "ref-filter.h" #include "strbuf.h" #include "strvec.h" -#include "commit-reach.h" static char const * const for_each_ref_usage[] = { N_("git for-each-ref [<options>] [<pattern>]"), @@ -19,16 +18,12 @@ static char const * const for_each_ref_usage[] = { int cmd_for_each_ref(int argc, const char **argv, const char *prefix) { - int i; struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; - int maxcount = 0, icase = 0, omit_empty = 0; - struct ref_array array; + int icase = 0, include_root_refs = 0, from_stdin = 0; struct ref_filter filter = REF_FILTER_INIT; struct ref_format format = REF_FORMAT_INIT; - struct strbuf output = STRBUF_INIT; - struct strbuf err = STRBUF_INIT; - int from_stdin = 0; + unsigned int flags = FILTER_REFS_REGULAR; struct strvec vec = STRVEC_INIT; struct option opts[] = { @@ -40,11 +35,11 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) N_("quote placeholders suitably for python"), QUOTE_PYTHON), OPT_BIT(0 , "tcl", &format.quote_style, N_("quote placeholders suitably for Tcl"), QUOTE_TCL), - OPT_BOOL(0, "omit-empty", &omit_empty, + OPT_BOOL(0, "omit-empty", &format.array_opts.omit_empty, N_("do not output a newline after empty formatted refs")), OPT_GROUP(""), - OPT_INTEGER( 0 , "count", &maxcount, N_("show only <n> matched refs")), + OPT_INTEGER( 0 , "count", &format.array_opts.max_count, N_("show only <n> matched refs")), OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")), OPT__COLOR(&format.use_color, N_("respect format colors")), OPT_REF_FILTER_EXCLUDE(&filter), @@ -58,18 +53,20 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) OPT_NO_CONTAINS(&filter.no_commit, N_("print only refs which don't contain the commit")), OPT_BOOL(0, "ignore-case", &icase, N_("sorting and filtering are case insensitive")), OPT_BOOL(0, "stdin", &from_stdin, N_("read reference patterns from stdin")), + OPT_BOOL(0, "include-root-refs", &include_root_refs, N_("also include HEAD ref and pseudorefs")), OPT_END(), }; - memset(&array, 0, sizeof(array)); - format.format = "%(objectname) %(objecttype)\t%(refname)"; git_config(git_default_config, NULL); + /* Set default (refname) sorting */ + string_list_append(&sorting_options, "refname"); + parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0); - if (maxcount < 0) { - error("invalid --count argument: `%d'", maxcount); + if (format.array_opts.max_count < 0) { + error("invalid --count argument: `%d'", format.array_opts.max_count); usage_with_options(for_each_ref_usage, opts); } if (HAS_MULTI_BITS(format.quote_style)) { @@ -100,27 +97,12 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) filter.name_patterns = argv; } + if (include_root_refs) + flags |= FILTER_REFS_ROOT_REFS; + filter.match_as_path = 1; - filter_refs(&array, &filter, FILTER_REFS_ALL); - filter_ahead_behind(the_repository, &format, &array); - - ref_array_sort(sorting, &array); - - if (!maxcount || array.nr < maxcount) - maxcount = array.nr; - for (i = 0; i < maxcount; i++) { - strbuf_reset(&err); - strbuf_reset(&output); - if (format_ref_array_item(array.items[i], &format, &output, &err)) - die("%s", err.buf); - fwrite(output.buf, 1, output.len, stdout); - if (output.len || !omit_empty) - putchar('\n'); - } + filter_and_format_refs(&filter, flags, sorting, &format); - strbuf_release(&err); - strbuf_release(&output); - ref_array_clear(&array); ref_filter_clear(&filter); ref_sorting_release(sorting); strvec_clear(&vec); diff --git a/builtin/fsck.c b/builtin/fsck.c index 611925905e..f892487c9b 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -10,13 +10,10 @@ #include "refs.h" #include "pack.h" #include "cache-tree.h" -#include "tree-walk.h" #include "fsck.h" #include "parse-options.h" -#include "dir.h" #include "progress.h" #include "streaming.h" -#include "decorate.h" #include "packfile.h" #include "object-file.h" #include "object-name.h" @@ -512,9 +509,7 @@ static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid return 0; } -static int fsck_handle_reflog(const char *logname, - const struct object_id *oid UNUSED, - int flag UNUSED, void *cb_data) +static int fsck_handle_reflog(const char *logname, void *cb_data) { struct strbuf refname = STRBUF_INIT; diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 5d01db5c02..1593713f4c 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -1,19 +1,20 @@ #include "builtin.h" #include "abspath.h" #include "config.h" +#include "dir.h" #include "environment.h" #include "gettext.h" #include "parse-options.h" #include "fsmonitor-ll.h" #include "fsmonitor-ipc.h" -#include "fsmonitor-path-utils.h" #include "fsmonitor-settings.h" #include "compat/fsmonitor/fsm-health.h" #include "compat/fsmonitor/fsm-listen.h" #include "fsmonitor--daemon.h" +#include "repository.h" #include "simple-ipc.h" #include "khash.h" -#include "pkt-line.h" +#include "run-command.h" #include "trace.h" #include "trace2.h" diff --git a/builtin/gc.c b/builtin/gc.c index 7c11d5ebef..cb80ced6cb 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1543,19 +1543,18 @@ static int maintenance_register(int argc, const char **argv, const char *prefix) if (!found) { int rc; - char *user_config = NULL, *xdg_config = NULL; + char *global_config_file = NULL; if (!config_file) { - git_global_config(&user_config, &xdg_config); - config_file = user_config; - if (!user_config) - die(_("$HOME not set")); + global_config_file = git_global_config(); + config_file = global_config_file; } + if (!config_file) + die(_("$HOME not set")); rc = git_config_set_multivar_in_file_gently( config_file, "maintenance.repo", maintpath, CONFIG_REGEX_NONE, 0); - free(user_config); - free(xdg_config); + free(global_config_file); if (rc) die(_("unable to add '%s' value of '%s'"), @@ -1612,18 +1611,18 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi if (found) { int rc; - char *user_config = NULL, *xdg_config = NULL; + char *global_config_file = NULL; + if (!config_file) { - git_global_config(&user_config, &xdg_config); - config_file = user_config; - if (!user_config) - die(_("$HOME not set")); + global_config_file = git_global_config(); + config_file = global_config_file; } + if (!config_file) + die(_("$HOME not set")); rc = git_config_set_multivar_in_file_gently( config_file, key, NULL, maintpath, CONFIG_FLAGS_MULTI_REPLACE | CONFIG_FLAGS_FIXED_VALUE); - free(user_config); - free(xdg_config); + free(global_config_file); if (rc && (!force || rc == CONFIG_NOTHING_SET)) diff --git a/builtin/get-tar-commit-id.c b/builtin/get-tar-commit-id.c index 20d0dfe9cf..66a7389f9f 100644 --- a/builtin/get-tar-commit-id.c +++ b/builtin/get-tar-commit-id.c @@ -4,7 +4,6 @@ #include "builtin.h" #include "commit.h" #include "tar.h" -#include "quote.h" static const char builtin_get_tar_commit_id_usage[] = "git get-tar-commit-id"; diff --git a/builtin/grep.c b/builtin/grep.c index fe78d4c98b..982bcfc4b1 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -9,15 +9,11 @@ #include "hex.h" #include "repository.h" #include "config.h" -#include "blob.h" -#include "tree.h" -#include "commit.h" #include "tag.h" #include "tree-walk.h" #include "parse-options.h" #include "string-list.h" #include "run-command.h" -#include "userdiff.h" #include "grep.h" #include "quote.h" #include "dir.h" @@ -575,6 +571,8 @@ static int grep_cache(struct grep_opt *opt, data = repo_read_object_file(the_repository, &ce->oid, &type, &size); + if (!data) + die(_("unable to read tree %s"), oid_to_hex(&ce->oid)); init_tree_desc(&tree, data, size); hit |= grep_tree(opt, pathspec, &tree, &name, 0, 0); diff --git a/builtin/hash-object.c b/builtin/hash-object.c index 5ffec99dce..82ca6d2bfd 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -14,7 +14,6 @@ #include "blob.h" #include "quote.h" #include "parse-options.h" -#include "exec-cmd.h" #include "setup.h" #include "strbuf.h" #include "write-or-die.h" diff --git a/builtin/hook.c b/builtin/hook.c index 09b51a6487..5234693a94 100644 --- a/builtin/hook.c +++ b/builtin/hook.c @@ -3,7 +3,6 @@ #include "gettext.h" #include "hook.h" #include "parse-options.h" -#include "strbuf.h" #include "strvec.h" #define BUILTIN_HOOK_RUN_USAGE \ diff --git a/builtin/index-pack.c b/builtin/index-pack.c index dda94a9f46..a3a37bd215 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -8,11 +8,9 @@ #include "csum-file.h" #include "blob.h" #include "commit.h" -#include "tag.h" #include "tree.h" #include "progress.h" #include "fsck.h" -#include "exec-cmd.h" #include "strbuf.h" #include "streaming.h" #include "thread-utils.h" @@ -26,7 +24,7 @@ #include "setup.h" static const char index_pack_usage[] = -"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])"; +"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict[=<msg-id>=<severity>...]] [--fsck-objects[=<msg-id>=<severity>...]] (<pack-file> | --stdin [--fix-thin] [<pack-file>])"; struct object_entry { struct pack_idx_entry idx; @@ -1257,6 +1255,7 @@ static void resolve_deltas(void) base_cache_limit = delta_base_cache_limit * nr_threads; if (nr_threads > 1 || getenv("GIT_FORCE_THREADS")) { init_thread(); + work_lock(); for (i = 0; i < nr_threads; i++) { int ret = pthread_create(&thread_data[i].thread, NULL, threaded_second_pass, thread_data + i); @@ -1264,6 +1263,7 @@ static void resolve_deltas(void) die(_("unable to create thread: %s"), strerror(ret)); } + work_unlock(); for (i = 0; i < nr_threads; i++) pthread_join(thread_data[i].thread, NULL); cleanup_thread(); @@ -1785,8 +1785,9 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) } else if (!strcmp(arg, "--check-self-contained-and-connected")) { strict = 1; check_self_contained_and_connected = 1; - } else if (!strcmp(arg, "--fsck-objects")) { + } else if (skip_to_optional_arg(arg, "--fsck-objects", &arg)) { do_fsck_object = 1; + fsck_set_msg_types(&fsck_options, arg); } else if (!strcmp(arg, "--verify")) { verify = 1; } else if (!strcmp(arg, "--verify-stat")) { diff --git a/builtin/init-db.c b/builtin/init-db.c index cb727c826f..0170469b84 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -5,12 +5,13 @@ */ #include "builtin.h" #include "abspath.h" -#include "config.h" #include "environment.h" #include "gettext.h" #include "object-file.h" #include "parse-options.h" #include "path.h" +#include "refs.h" +#include "repository.h" #include "setup.h" #include "strbuf.h" @@ -57,6 +58,7 @@ static int shared_callback(const struct option *opt, const char *arg, int unset) static const char *const init_db_usage[] = { N_("git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" + " [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]"), NULL @@ -76,8 +78,10 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) const char *template_dir = NULL; unsigned int flags = 0; const char *object_format = NULL; + const char *ref_format = NULL; const char *initial_branch = NULL; int hash_algo = GIT_HASH_UNKNOWN; + unsigned int ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN; int init_shared_repository = -1; const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, N_("template-directory"), @@ -95,6 +99,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) N_("override the name of the initial branch")), OPT_STRING(0, "object-format", &object_format, N_("hash"), N_("specify the hash algorithm to use")), + OPT_STRING(0, "ref-format", &ref_format, N_("format"), + N_("specify the reference format to use")), OPT_END() }; @@ -158,6 +164,12 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) die(_("unknown hash algorithm '%s'"), object_format); } + if (ref_format) { + ref_storage_format = ref_storage_format_by_name(ref_format); + if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN) + die(_("unknown ref storage format '%s'"), ref_format); + } + if (init_shared_repository != -1) set_shared_repository(init_shared_repository); @@ -236,5 +248,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) flags |= INIT_DB_EXIST_OK; return init_db(git_dir, real_git_dir, template_dir, hash_algo, - initial_branch, init_shared_repository, flags); + ref_storage_format, initial_branch, + init_shared_repository, flags); } diff --git a/builtin/log.c b/builtin/log.c index ba775d7b5c..db1808d7c1 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -26,7 +26,6 @@ #include "tag.h" #include "reflog-walk.h" #include "patch-ids.h" -#include "run-command.h" #include "shortlog.h" #include "remote.h" #include "string-list.h" @@ -36,7 +35,6 @@ #include "streaming.h" #include "version.h" #include "mailmap.h" -#include "gpg-interface.h" #include "progress.h" #include "commit-slab.h" #include "repository.h" @@ -594,8 +592,11 @@ static int git_log_config(const char *var, const char *value, decoration_style = 0; /* maybe warn? */ return 0; } - if (!strcmp(var, "log.diffmerges")) + if (!strcmp(var, "log.diffmerges")) { + if (!value) + return config_error_nonbool(var); return diff_merges_config(value); + } if (!strcmp(var, "log.showroot")) { default_show_root = git_config_bool(var, value); return 0; @@ -1364,6 +1365,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file, pp.date_mode.type = DATE_RFC2822; pp.rev = rev; pp.print_email_subject = 1; + pp.encode_email_headers = rev->encode_email_headers; pp_user_info(&pp, NULL, &sb, committer, encoding); prepare_cover_text(&pp, description_file, branch_name, &sb, encoding, need_8bit_cte); diff --git a/builtin/ls-files.c b/builtin/ls-files.c index a0229c3277..92f94e65bf 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -14,19 +14,15 @@ #include "gettext.h" #include "object-name.h" #include "strbuf.h" -#include "tree.h" -#include "cache-tree.h" #include "parse-options.h" #include "resolve-undo.h" #include "string-list.h" #include "path.h" #include "pathspec.h" #include "read-cache.h" -#include "run-command.h" #include "setup.h" #include "sparse-index.h" #include "submodule.h" -#include "submodule-config.h" #include "object-store.h" #include "hex.h" diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index fc76575430..e8d65ebbdc 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -5,7 +5,6 @@ #include "pkt-line.h" #include "ref-filter.h" #include "remote.h" -#include "refs.h" #include "parse-options.h" #include "wildmatch.h" @@ -58,6 +57,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) struct transport *transport; const struct ref *ref; struct ref_array ref_array; + struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; struct option options[] = { @@ -141,13 +141,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) item->symref = xstrdup_or_null(ref->symref); } - if (sorting_options.nr) { - struct ref_sorting *sorting; - - sorting = ref_sorting_options(&sorting_options); - ref_array_sort(sorting, &ref_array); - ref_sorting_release(sorting); - } + sorting = ref_sorting_options(&sorting_options); + ref_array_sort(sorting, &ref_array); for (i = 0; i < ref_array.nr; i++) { const struct ref_array_item *ref = ref_array.items[i]; @@ -157,6 +152,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) status = 0; /* we found something */ } + ref_sorting_release(sorting); ref_array_clear(&ref_array); if (transport_disconnect(transport)) status = 1; diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 209d2dc0d5..e4a891337c 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -9,9 +9,7 @@ #include "hex.h" #include "object-name.h" #include "object-store-ll.h" -#include "blob.h" #include "tree.h" -#include "commit.h" #include "path.h" #include "quote.h" #include "parse-options.h" diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index 53b55dd71c..53a22645da 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -6,7 +6,6 @@ #include "abspath.h" #include "environment.h" #include "gettext.h" -#include "utf8.h" #include "strbuf.h" #include "mailinfo.h" #include "parse-options.h" diff --git a/builtin/merge-base.c b/builtin/merge-base.c index e68b7fe45d..d26e8fbf6f 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -3,9 +3,6 @@ #include "commit.h" #include "gettext.h" #include "hex.h" -#include "refs.h" -#include "diff.h" -#include "revision.h" #include "object-name.h" #include "parse-options.h" #include "repository.h" diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 832c93d8d5..1f987334a3 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "abspath.h" +#include "diff.h" #include "hex.h" #include "object-name.h" #include "object-store.h" @@ -28,6 +29,30 @@ static int label_cb(const struct option *opt, const char *arg, int unset) return 0; } +static int set_diff_algorithm(xpparam_t *xpp, + const char *alg) +{ + long diff_algorithm = parse_algorithm_value(alg); + if (diff_algorithm < 0) + return -1; + xpp->flags = (xpp->flags & ~XDF_DIFF_ALGORITHM_MASK) | diff_algorithm; + return 0; +} + +static int diff_algorithm_cb(const struct option *opt, + const char *arg, int unset) +{ + xpparam_t *xpp = opt->value; + + BUG_ON_OPT_NEG(unset); + + if (set_diff_algorithm(xpp, arg)) + return error(_("option diff-algorithm accepts \"myers\", " + "\"minimal\", \"patience\" and \"histogram\"")); + + return 0; +} + int cmd_merge_file(int argc, const char **argv, const char *prefix) { const char *names[3] = { 0 }; @@ -48,6 +73,9 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix) XDL_MERGE_FAVOR_THEIRS), OPT_SET_INT(0, "union", &xmp.favor, N_("for conflicts, use a union version"), XDL_MERGE_FAVOR_UNION), + OPT_CALLBACK_F(0, "diff-algorithm", &xmp.xpp, N_("<algorithm>"), + N_("choose a diff algorithm"), + PARSE_OPT_NONEG, diff_algorithm_cb), OPT_INTEGER(0, "marker-size", &xmp.marker_size, N_("for conflicts, use this marker size")), OPT__QUIET(&quiet, N_("do not warn about conflicts")), diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c index 3366699657..c2ce044a20 100644 --- a/builtin/merge-recursive.c +++ b/builtin/merge-recursive.c @@ -1,13 +1,10 @@ #include "builtin.h" #include "advice.h" -#include "commit.h" #include "gettext.h" #include "hash.h" -#include "tag.h" #include "merge-recursive.h" #include "object-name.h" #include "repository.h" -#include "xdiff-interface.h" static const char builtin_merge_recursive_usage[] = "git %s <base>... -- <head> <remote> ..."; diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index a35e0452d6..3bdec53fbe 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -13,7 +13,6 @@ #include "parse-options.h" #include "repository.h" #include "blob.h" -#include "exec-cmd.h" #include "merge-blobs.h" #include "quote.h" #include "tree.h" @@ -577,7 +576,8 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix) if (o.mode == MODE_TRIVIAL) die(_("--trivial-merge is incompatible with all other options")); if (merge_base) - die(_("--merge-base is incompatible with --stdin")); + die(_("options '%s' and '%s' cannot be used together"), + "--merge-base", "--stdin"); line_termination = '\0'; while (strbuf_getline_lf(&buf, stdin) != EOF) { struct strbuf **split; diff --git a/builtin/merge.c b/builtin/merge.c index d748d46e13..935c8a57dd 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -31,8 +31,6 @@ #include "unpack-trees.h" #include "cache-tree.h" #include "dir.h" -#include "utf8.h" -#include "log-tree.h" #include "color.h" #include "rerere.h" #include "help.h" @@ -42,10 +40,8 @@ #include "resolve-undo.h" #include "remote.h" #include "fmt-merge-msg.h" -#include "gpg-interface.h" #include "sequencer.h" #include "string-list.h" -#include "packfile.h" #include "tag.h" #include "alias.h" #include "branch.h" @@ -196,8 +192,7 @@ static struct strategy *get_strategy(const char *name) int j, found = 0; struct cmdname *ent = main_cmds.names[i]; for (j = 0; !found && j < ARRAY_SIZE(all_strategy); j++) - if (!strncmp(ent->name, all_strategy[j].name, ent->len) - && !all_strategy[j].name[ent->len]) + if (!xstrncmpz(all_strategy[j].name, ent->name, ent->len)) found = 1; if (!found) add_cmdname(¬_strategies, ent->name, ent->len); @@ -480,7 +475,7 @@ static void finish(struct commit *head_commit, run_hooks_l("post-merge", squash ? "1" : "0", NULL); if (new_head) - apply_autostash(git_path_merge_autostash(the_repository)); + apply_autostash_ref(the_repository, "MERGE_AUTOSTASH"); strbuf_release(&reflog_message); } @@ -869,7 +864,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) _(no_scissors_editor_comment), comment_line_char); } if (signoff) - append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0); + append_signoff(&msg, ignored_log_message_bytes(msg.buf, msg.len), 0); write_merge_heads(remoteheads); write_file_buf(git_path_merge_msg(the_repository), msg.buf, msg.len); if (run_commit_hook(0 < option_edit, get_index_file(), NULL, @@ -1319,7 +1314,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (abort_current_merge) { int nargc = 2; const char *nargv[] = {"reset", "--merge", NULL}; - struct strbuf stash_oid = STRBUF_INIT; + char stash_oid_hex[GIT_MAX_HEXSZ + 1]; + struct object_id stash_oid = {0}; if (orig_argc != 2) usage_msg_opt(_("--abort expects no arguments"), @@ -1328,17 +1324,17 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (!file_exists(git_path_merge_head(the_repository))) die(_("There is no merge to abort (MERGE_HEAD missing).")); - if (read_oneliner(&stash_oid, git_path_merge_autostash(the_repository), - READ_ONELINER_SKIP_IF_EMPTY)) - unlink(git_path_merge_autostash(the_repository)); + if (!read_ref("MERGE_AUTOSTASH", &stash_oid)) + delete_ref("", "MERGE_AUTOSTASH", &stash_oid, REF_NO_DEREF); /* Invoke 'git reset --merge' */ ret = cmd_reset(nargc, nargv, prefix); - if (stash_oid.len) - apply_autostash_oid(stash_oid.buf); + if (!is_null_oid(&stash_oid)) { + oid_to_hex_r(stash_oid_hex, &stash_oid); + apply_autostash_oid(stash_oid_hex); + } - strbuf_release(&stash_oid); goto done; } @@ -1567,13 +1563,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } if (autostash) - create_autostash(the_repository, - git_path_merge_autostash(the_repository)); + create_autostash_ref(the_repository, "MERGE_AUTOSTASH"); if (checkout_fast_forward(the_repository, &head_commit->object.oid, &commit->object.oid, overwrite_ignore)) { - apply_autostash(git_path_merge_autostash(the_repository)); + apply_autostash_ref(the_repository, "MERGE_AUTOSTASH"); ret = 1; goto done; } @@ -1659,8 +1654,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) die_ff_impossible(); if (autostash) - create_autostash(the_repository, - git_path_merge_autostash(the_repository)); + create_autostash_ref(the_repository, "MERGE_AUTOSTASH"); /* We are going to make a new commit. */ git_committer_info(IDENT_STRICT); @@ -1745,7 +1739,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) else fprintf(stderr, _("Merge with strategy %s failed.\n"), use_strategies[0]->name); - apply_autostash(git_path_merge_autostash(the_repository)); + apply_autostash_ref(the_repository, "MERGE_AUTOSTASH"); ret = 2; goto done; } else if (best_strategy == wt_strategy) diff --git a/builtin/mktag.c b/builtin/mktag.c index d8e0b5afc0..4767f1a97e 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -3,7 +3,6 @@ #include "hex.h" #include "parse-options.h" #include "strbuf.h" -#include "tag.h" #include "replace-object.h" #include "object-file.h" #include "object-store-ll.h" diff --git a/builtin/mv.c b/builtin/mv.c index c596515ad0..22e64fc290 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -15,7 +15,6 @@ #include "pathspec.h" #include "lockfile.h" #include "dir.h" -#include "cache-tree.h" #include "string-list.h" #include "parse-options.h" #include "read-cache-ll.h" diff --git a/builtin/name-rev.c b/builtin/name-rev.c index 2dd1807c4e..ad9930c831 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -15,6 +15,7 @@ #include "commit-slab.h" #include "commit-graph.h" #include "wildmatch.h" +#include "mem-pool.h" /* * One day. See the 'name a rev shortly after epoch' test in t6120 when @@ -155,30 +156,25 @@ static struct rev_name *create_or_update_name(struct commit *commit, return name; } -static char *get_parent_name(const struct rev_name *name, int parent_number) +static char *get_parent_name(const struct rev_name *name, int parent_number, + struct mem_pool *string_pool) { - struct strbuf sb = STRBUF_INIT; size_t len; strip_suffix(name->tip_name, "^0", &len); if (name->generation > 0) { - strbuf_grow(&sb, len + - 1 + decimal_width(name->generation) + - 1 + decimal_width(parent_number)); - strbuf_addf(&sb, "%.*s~%d^%d", (int)len, name->tip_name, - name->generation, parent_number); + return mem_pool_strfmt(string_pool, "%.*s~%d^%d", + (int)len, name->tip_name, + name->generation, parent_number); } else { - strbuf_grow(&sb, len + - 1 + decimal_width(parent_number)); - strbuf_addf(&sb, "%.*s^%d", (int)len, name->tip_name, - parent_number); + return mem_pool_strfmt(string_pool, "%.*s^%d", + (int)len, name->tip_name, parent_number); } - return strbuf_detach(&sb, NULL); } static void name_rev(struct commit *start_commit, const char *tip_name, timestamp_t taggerdate, - int from_tag, int deref) + int from_tag, int deref, struct mem_pool *string_pool) { struct prio_queue queue; struct commit *commit; @@ -195,9 +191,10 @@ static void name_rev(struct commit *start_commit, if (!start_name) return; if (deref) - start_name->tip_name = xstrfmt("%s^0", tip_name); + start_name->tip_name = mem_pool_strfmt(string_pool, "%s^0", + tip_name); else - start_name->tip_name = xstrdup(tip_name); + start_name->tip_name = mem_pool_strdup(string_pool, tip_name); memset(&queue, 0, sizeof(queue)); /* Use the prio_queue as LIFO */ prio_queue_put(&queue, start_commit); @@ -235,7 +232,8 @@ static void name_rev(struct commit *start_commit, if (parent_number > 1) parent_name->tip_name = get_parent_name(name, - parent_number); + parent_number, + string_pool); else parent_name->tip_name = name->tip_name; ALLOC_GROW(parents_to_queue, @@ -415,7 +413,7 @@ static int name_ref(const char *path, const struct object_id *oid, return 0; } -static void name_tips(void) +static void name_tips(struct mem_pool *string_pool) { int i; @@ -428,7 +426,7 @@ static void name_tips(void) struct tip_table_entry *e = &tip_table.table[i]; if (e->commit) { name_rev(e->commit, e->refname, e->taggerdate, - e->from_tag, e->deref); + e->from_tag, e->deref, string_pool); } } } @@ -561,6 +559,7 @@ static void name_rev_line(char *p, struct name_ref_data *data) int cmd_name_rev(int argc, const char **argv, const char *prefix) { + struct mem_pool string_pool; struct object_array revs = OBJECT_ARRAY_INIT; int all = 0, annotate_stdin = 0, transform_stdin = 0, allow_undefined = 1, always = 0, peel_tag = 0; struct name_ref_data data = { 0, 0, STRING_LIST_INIT_NODUP, STRING_LIST_INIT_NODUP }; @@ -587,6 +586,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) OPT_END(), }; + mem_pool_init(&string_pool, 0); init_commit_rev_name(&rev_names); git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, opts, name_rev_usage, 0); @@ -648,7 +648,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) adjust_cutoff_timestamp_for_slop(); for_each_ref(name_ref, &data); - name_tips(); + name_tips(&string_pool); if (annotate_stdin) { struct strbuf sb = STRBUF_INIT; @@ -676,6 +676,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) always, allow_undefined, data.name_only); } + UNLEAK(string_pool); UNLEAK(revs); return 0; } diff --git a/builtin/notes.c b/builtin/notes.c index 9f38863dd5..caf20fd5bd 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -9,7 +9,6 @@ #include "builtin.h" #include "config.h" -#include "alloc.h" #include "editor.h" #include "environment.h" #include "gettext.h" @@ -19,7 +18,6 @@ #include "object-store-ll.h" #include "path.h" #include "repository.h" -#include "blob.h" #include "pretty.h" #include "refs.h" #include "exec-cmd.h" @@ -718,9 +716,11 @@ static int append_edit(int argc, const char **argv, const char *prefix) struct strbuf buf = STRBUF_INIT; char *prev_buf = repo_read_object_file(the_repository, note, &type, &size); - if (prev_buf && size) + if (!prev_buf) + die(_("unable to read %s"), oid_to_hex(note)); + if (size) strbuf_add(&buf, prev_buf, size); - if (d.buf.len && prev_buf && size) + if (d.buf.len && size) append_separator(&buf); strbuf_insert(&d.buf, 0, buf.buf, buf.len); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 89a8b5a976..329aeac804 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -6,10 +6,8 @@ #include "config.h" #include "attr.h" #include "object.h" -#include "blob.h" #include "commit.h" #include "tag.h" -#include "tree.h" #include "delta.h" #include "pack.h" #include "pack-revindex.h" @@ -18,7 +16,6 @@ #include "diff.h" #include "revision.h" #include "list-objects.h" -#include "list-objects-filter.h" #include "list-objects-filter-options.h" #include "pack-objects.h" #include "progress.h" @@ -221,13 +218,19 @@ static int thin; static int num_preferred_base; static struct progress *progress_state; -static struct packed_git *reuse_packfile; +static struct bitmapped_pack *reuse_packfiles; +static size_t reuse_packfiles_nr; +static size_t reuse_packfiles_used_nr; static uint32_t reuse_packfile_objects; static struct bitmap *reuse_packfile_bitmap; static int use_bitmap_index_default = 1; static int use_bitmap_index = -1; -static int allow_pack_reuse = 1; +static enum { + NO_PACK_REUSE = 0, + SINGLE_PACK_REUSE, + MULTI_PACK_REUSE, +} allow_pack_reuse = SINGLE_PACK_REUSE; static enum { WRITE_BITMAP_FALSE = 0, WRITE_BITMAP_QUIET, @@ -1013,7 +1016,9 @@ static off_t find_reused_offset(off_t where) return reused_chunks[lo-1].difference; } -static void write_reused_pack_one(size_t pos, struct hashfile *out, +static void write_reused_pack_one(struct packed_git *reuse_packfile, + size_t pos, struct hashfile *out, + off_t pack_start, struct pack_window **w_curs) { off_t offset, next, cur; @@ -1023,7 +1028,8 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out, offset = pack_pos_to_offset(reuse_packfile, pos); next = pack_pos_to_offset(reuse_packfile, pos + 1); - record_reused_object(offset, offset - hashfile_total(out)); + record_reused_object(offset, + offset - (hashfile_total(out) - pack_start)); cur = offset; type = unpack_object_header(reuse_packfile, w_curs, &cur, &size); @@ -1091,41 +1097,93 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out, copy_pack_data(out, reuse_packfile, w_curs, offset, next - offset); } -static size_t write_reused_pack_verbatim(struct hashfile *out, +static size_t write_reused_pack_verbatim(struct bitmapped_pack *reuse_packfile, + struct hashfile *out, + off_t pack_start, struct pack_window **w_curs) { - size_t pos = 0; + size_t pos = reuse_packfile->bitmap_pos; + size_t end; + + if (pos % BITS_IN_EWORD) { + size_t word_pos = (pos / BITS_IN_EWORD); + size_t offset = pos % BITS_IN_EWORD; + size_t last; + eword_t word = reuse_packfile_bitmap->words[word_pos]; + + if (offset + reuse_packfile->bitmap_nr < BITS_IN_EWORD) + last = offset + reuse_packfile->bitmap_nr; + else + last = BITS_IN_EWORD; + + for (; offset < last; offset++) { + if (word >> offset == 0) + return word_pos; + if (!bitmap_get(reuse_packfile_bitmap, + word_pos * BITS_IN_EWORD + offset)) + return word_pos; + } + + pos += BITS_IN_EWORD - (pos % BITS_IN_EWORD); + } + + /* + * Now we're going to copy as many whole eword_t's as possible. + * "end" is the index of the last whole eword_t we copy, but + * there may be additional bits to process. Those are handled + * individually by write_reused_pack(). + * + * Begin by advancing to the first word boundary in range of the + * bit positions occupied by objects in "reuse_packfile". Then + * pick the last word boundary in the same range. If we have at + * least one word's worth of bits to process, continue on. + */ + end = reuse_packfile->bitmap_pos + reuse_packfile->bitmap_nr; + if (end % BITS_IN_EWORD) + end -= end % BITS_IN_EWORD; + if (pos >= end) + return reuse_packfile->bitmap_pos / BITS_IN_EWORD; + + while (pos < end && + reuse_packfile_bitmap->words[pos / BITS_IN_EWORD] == (eword_t)~0) + pos += BITS_IN_EWORD; - while (pos < reuse_packfile_bitmap->word_alloc && - reuse_packfile_bitmap->words[pos] == (eword_t)~0) - pos++; + if (pos > end) + pos = end; - if (pos) { - off_t to_write; + if (reuse_packfile->bitmap_pos < pos) { + off_t pack_start_off = pack_pos_to_offset(reuse_packfile->p, 0); + off_t pack_end_off = pack_pos_to_offset(reuse_packfile->p, + pos - reuse_packfile->bitmap_pos); - written = (pos * BITS_IN_EWORD); - to_write = pack_pos_to_offset(reuse_packfile, written) - - sizeof(struct pack_header); + written += pos - reuse_packfile->bitmap_pos; /* We're recording one chunk, not one object. */ - record_reused_object(sizeof(struct pack_header), 0); + record_reused_object(pack_start_off, + pack_start_off - (hashfile_total(out) - pack_start)); hashflush(out); - copy_pack_data(out, reuse_packfile, w_curs, - sizeof(struct pack_header), to_write); + copy_pack_data(out, reuse_packfile->p, w_curs, + pack_start_off, pack_end_off - pack_start_off); display_progress(progress_state, written); } - return pos; + if (pos % BITS_IN_EWORD) + BUG("attempted to jump past a word boundary to %"PRIuMAX, + (uintmax_t)pos); + return pos / BITS_IN_EWORD; } -static void write_reused_pack(struct hashfile *f) +static void write_reused_pack(struct bitmapped_pack *reuse_packfile, + struct hashfile *f) { - size_t i = 0; + size_t i = reuse_packfile->bitmap_pos / BITS_IN_EWORD; uint32_t offset; + off_t pack_start = hashfile_total(f) - sizeof(struct pack_header); struct pack_window *w_curs = NULL; if (allow_ofs_delta) - i = write_reused_pack_verbatim(f, &w_curs); + i = write_reused_pack_verbatim(reuse_packfile, f, pack_start, + &w_curs); for (; i < reuse_packfile_bitmap->word_alloc; ++i) { eword_t word = reuse_packfile_bitmap->words[i]; @@ -1136,16 +1194,23 @@ static void write_reused_pack(struct hashfile *f) break; offset += ewah_bit_ctz64(word >> offset); + if (pos + offset < reuse_packfile->bitmap_pos) + continue; + if (pos + offset >= reuse_packfile->bitmap_pos + reuse_packfile->bitmap_nr) + goto done; /* * Can use bit positions directly, even for MIDX * bitmaps. See comment in try_partial_reuse() * for why. */ - write_reused_pack_one(pos + offset, f, &w_curs); + write_reused_pack_one(reuse_packfile->p, + pos + offset - reuse_packfile->bitmap_pos, + f, pack_start, &w_curs); display_progress(progress_state, ++written); } } +done: unuse_pack(&w_curs); } @@ -1197,9 +1262,14 @@ static void write_pack_file(void) offset = write_pack_header(f, nr_remaining); - if (reuse_packfile) { + if (reuse_packfiles_nr) { assert(pack_to_stdout); - write_reused_pack(f); + for (j = 0; j < reuse_packfiles_nr; j++) { + reused_chunks_nr = 0; + write_reused_pack(&reuse_packfiles[j], f); + if (reused_chunks_nr) + reuse_packfiles_used_nr++; + } offset = hashfile_total(f); } @@ -3175,7 +3245,19 @@ static int git_pack_config(const char *k, const char *v, return 0; } if (!strcmp(k, "pack.allowpackreuse")) { - allow_pack_reuse = git_config_bool(k, v); + int res = git_parse_maybe_bool_text(v); + if (res < 0) { + if (!strcasecmp(v, "single")) + allow_pack_reuse = SINGLE_PACK_REUSE; + else if (!strcasecmp(v, "multi")) + allow_pack_reuse = MULTI_PACK_REUSE; + else + die(_("invalid pack.allowPackReuse value: '%s'"), v); + } else if (res) { + allow_pack_reuse = SINGLE_PACK_REUSE; + } else { + allow_pack_reuse = NO_PACK_REUSE; + } return 0; } if (!strcmp(k, "pack.threads")) { @@ -3204,7 +3286,7 @@ static int git_pack_config(const char *k, const char *v, return 0; } if (!strcmp(k, "uploadpack.blobpackfileuri")) { - struct configured_exclusion *ex = xmalloc(sizeof(*ex)); + struct configured_exclusion *ex; const char *oid_end, *pack_end; /* * Stores the pack hash. This is not a true object ID, but is @@ -3212,6 +3294,10 @@ static int git_pack_config(const char *k, const char *v, */ struct object_id pack_hash; + if (!v) + return config_error_nonbool(k); + + ex = xmalloc(sizeof(*ex)); if (parse_oid_hex(v, &ex->e.oid, &oid_end) || *oid_end != ' ' || parse_oid_hex(oid_end + 1, &pack_hash, &pack_end) || @@ -3930,7 +4016,7 @@ static void loosen_unused_packed_objects(void) */ static int pack_options_allow_reuse(void) { - return allow_pack_reuse && + return allow_pack_reuse != NO_PACK_REUSE && pack_to_stdout && !ignore_packed_keep_on_disk && !ignore_packed_keep_in_core && @@ -3943,13 +4029,18 @@ static int get_object_list_from_bitmap(struct rev_info *revs) if (!(bitmap_git = prepare_bitmap_walk(revs, 0))) return -1; - if (pack_options_allow_reuse() && - !reuse_partial_packfile_from_bitmap( - bitmap_git, - &reuse_packfile, - &reuse_packfile_objects, - &reuse_packfile_bitmap)) { - assert(reuse_packfile_objects); + if (pack_options_allow_reuse()) + reuse_partial_packfile_from_bitmap(bitmap_git, + &reuse_packfiles, + &reuse_packfiles_nr, + &reuse_packfile_bitmap, + allow_pack_reuse == MULTI_PACK_REUSE); + + if (reuse_packfiles) { + reuse_packfile_objects = bitmap_popcount(reuse_packfile_bitmap); + if (!reuse_packfile_objects) + BUG("expected non-empty reuse bitmap"); + nr_result += reuse_packfile_objects; nr_seen += reuse_packfile_objects; display_progress(progress_state, nr_seen); @@ -4305,6 +4396,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) prepare_repo_settings(the_repository); if (sparse < 0) sparse = the_repository->settings.pack_use_sparse; + if (the_repository->settings.pack_use_multi_pack_reuse) + allow_pack_reuse = MULTI_PACK_REUSE; } reset_pack_idx_option(&pack_idx_opts); @@ -4517,11 +4610,20 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) fprintf_ln(stderr, _("Total %"PRIu32" (delta %"PRIu32")," " reused %"PRIu32" (delta %"PRIu32")," - " pack-reused %"PRIu32), + " pack-reused %"PRIu32" (from %"PRIuMAX")"), written, written_delta, reused, reused_delta, - reuse_packfile_objects); + reuse_packfile_objects, + (uintmax_t)reuse_packfiles_used_nr); + + trace2_data_intmax("pack-objects", the_repository, "written", written); + trace2_data_intmax("pack-objects", the_repository, "written/delta", written_delta); + trace2_data_intmax("pack-objects", the_repository, "reused", reused); + trace2_data_intmax("pack-objects", the_repository, "reused/delta", reused_delta); + trace2_data_intmax("pack-objects", the_repository, "pack-reused", reuse_packfile_objects); + trace2_data_intmax("pack-objects", the_repository, "packs-reused", reuse_packfiles_used_nr); cleanup: + clear_packing_data(&to_pack); list_objects_filter_release(&filter_options); strvec_clear(&rp); diff --git a/builtin/pull.c b/builtin/pull.c index be2b2c9ebc..73a68b75b0 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -14,7 +14,6 @@ #include "merge.h" #include "object-name.h" #include "parse-options.h" -#include "exec-cmd.h" #include "run-command.h" #include "oid-array.h" #include "remote.h" @@ -24,15 +23,11 @@ #include "rebase.h" #include "refs.h" #include "refspec.h" -#include "revision.h" #include "submodule.h" #include "submodule-config.h" -#include "tempfile.h" -#include "lockfile.h" #include "wt-status.h" #include "commit-reach.h" #include "sequencer.h" -#include "packfile.h" /** * Parses the value of --rebase. If value is a false value, returns diff --git a/builtin/push.c b/builtin/push.c index 2e708383c2..2fbb31c3ad 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -7,7 +7,6 @@ #include "config.h" #include "environment.h" #include "gettext.h" -#include "refs.h" #include "refspec.h" #include "run-command.h" #include "remote.h" @@ -392,7 +391,7 @@ static int push_with_options(struct transport *transport, struct refspec *rs, if (!is_empty_cas(&cas)) { if (!transport->smart_options) die("underlying transport does not support --%s option", - CAS_OPT_NAME); + "force-with-lease"); transport->smart_options->cas = &cas; } @@ -526,26 +525,21 @@ static int git_push_config(const char *k, const char *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)) { - switch (git_parse_maybe_bool(value)) { - case 0: - set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_NEVER); - break; - case 1: - set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_ALWAYS); - break; - default: - if (value && !strcasecmp(value, "if-asked")) - set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_IF_ASKED); - else - return error(_("invalid value for '%s'"), k); - } + switch (git_parse_maybe_bool(v)) { + case 0: + set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_NEVER); + break; + case 1: + set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_ALWAYS); + break; + default: + if (!strcasecmp(v, "if-asked")) + set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_IF_ASKED); + else + return error(_("invalid value for '%s'"), k); } } else if (!strcmp(k, "push.recursesubmodules")) { - const char *value; - if (!git_config_get_value("push.recursesubmodules", &value)) - recurse_submodules = parse_push_recurse_submodules_arg(k, value); + recurse_submodules = parse_push_recurse_submodules_arg(k, v); } else if (!strcmp(k, "submodule.recurse")) { int val = git_config_bool(k, v) ? RECURSE_SUBMODULES_ON_DEMAND : RECURSE_SUBMODULES_OFF; @@ -604,7 +598,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN), OPT_BIT( 0, "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN), OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE), - OPT_CALLBACK_F(0, CAS_OPT_NAME, &cas, N_("<refname>:<expect>"), + OPT_CALLBACK_F(0, "force-with-lease", &cas, N_("<refname>:<expect>"), N_("require old value of ref to be at this value"), PARSE_OPT_OPTARG | PARSE_OPT_LITERAL_ARGHELP, parseopt_push_cas_option), OPT_BIT(0, TRANS_OPT_FORCE_IF_INCLUDES, &flags, @@ -639,8 +633,10 @@ int cmd_push(int argc, const char **argv, const char *prefix) : &push_options_config); set_push_cert_flags(&flags, push_cert); - if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR)))) - die(_("options '%s' and '%s' cannot be used together"), "--delete", "--all/--branches/--mirror/--tags"); + die_for_incompatible_opt4(deleterefs, "--delete", + tags, "--tags", + flags & TRANSPORT_PUSH_ALL, "--all/--branches", + flags & TRANSPORT_PUSH_MIRROR, "--mirror"); if (deleterefs && argc < 2) die(_("--delete doesn't make sense without any refs")); @@ -677,19 +673,13 @@ int cmd_push(int argc, const char **argv, const char *prefix) flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE); if (flags & TRANSPORT_PUSH_ALL) { - if (tags) - die(_("options '%s' and '%s' cannot be used together"), "--all", "--tags"); if (argc >= 2) die(_("--all can't be combined with refspecs")); } if (flags & TRANSPORT_PUSH_MIRROR) { - if (tags) - die(_("options '%s' and '%s' cannot be used together"), "--mirror", "--tags"); if (argc >= 2) die(_("--mirror can't be combined with refspecs")); } - if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR)) - die(_("options '%s' and '%s' cannot be used together"), "--all", "--mirror"); if (!is_empty_cas(&cas) && (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES)) cas.use_force_if_includes = 1; diff --git a/builtin/range-diff.c b/builtin/range-diff.c index e455a4795c..f02cbac087 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -5,7 +5,6 @@ #include "range-diff.h" #include "config.h" #include "repository.h" -#include "revision.h" static const char * const builtin_range_diff_usage[] = { N_("git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"), diff --git a/builtin/read-tree.c b/builtin/read-tree.c index 8196ca9dd8..20e7db1973 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -16,14 +16,12 @@ #include "tree-walk.h" #include "cache-tree.h" #include "unpack-trees.h" -#include "dir.h" #include "parse-options.h" #include "repository.h" #include "resolve-undo.h" #include "setup.h" #include "sparse-index.h" #include "submodule.h" -#include "submodule-config.h" static int nr_trees; static int read_empty; diff --git a/builtin/rebase.c b/builtin/rebase.c index 9f8192e0a5..6ead9465a4 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -11,14 +11,10 @@ #include "gettext.h" #include "hex.h" #include "run-command.h" -#include "exec-cmd.h" #include "strvec.h" #include "dir.h" -#include "packfile.h" #include "refs.h" -#include "quote.h" #include "config.h" -#include "cache-tree.h" #include "unpack-trees.h" #include "lockfile.h" #include "object-file.h" @@ -519,7 +515,7 @@ static int finish_rebase(struct rebase_options *opts) int ret = 0; delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF); - unlink(git_path_auto_merge(the_repository)); + delete_ref(NULL, "AUTO_MERGE", NULL, REF_NO_DEREF); apply_autostash(state_dir_path("autostash", opts)); /* * We ignore errors in 'git maintenance run --auto', since the @@ -582,7 +578,6 @@ static int run_am(struct rebase_options *opts) { struct child_process am = CHILD_PROCESS_INIT; struct child_process format_patch = CHILD_PROCESS_INIT; - struct strbuf revisions = STRBUF_INIT; int status; char *rebased_patches; @@ -615,13 +610,6 @@ static int run_am(struct rebase_options *opts) return run_command(&am); } - strbuf_addf(&revisions, "%s...%s", - oid_to_hex(opts->root ? - /* this is now equivalent to !opts->upstream */ - &opts->onto->object.oid : - &opts->upstream->object.oid), - oid_to_hex(&opts->orig_head->object.oid)); - rebased_patches = xstrdup(git_path("rebased-patches")); format_patch.out = open(rebased_patches, O_WRONLY | O_CREAT | O_TRUNC, 0666); @@ -642,7 +630,12 @@ static int run_am(struct rebase_options *opts) if (opts->git_format_patch_opt.len) strvec_split(&format_patch.args, opts->git_format_patch_opt.buf); - strvec_push(&format_patch.args, revisions.buf); + strvec_pushf(&format_patch.args, "%s...%s", + oid_to_hex(opts->root ? + /* this is now equivalent to !opts->upstream */ + &opts->onto->object.oid : + &opts->upstream->object.oid), + oid_to_hex(&opts->orig_head->object.oid)); if (opts->restrict_revision) strvec_pushf(&format_patch.args, "^%s", oid_to_hex(&opts->restrict_revision->object.oid)); @@ -665,10 +658,8 @@ static int run_am(struct rebase_options *opts) "As a result, git cannot rebase them."), opts->revisions); - strbuf_release(&revisions); return status; } - strbuf_release(&revisions); am.in = open(rebased_patches, O_RDONLY); if (am.in < 0) { @@ -1263,7 +1254,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) die(_("options '%s' and '%s' cannot be used together"), "--root", "--fork-point"); if (options.action != ACTION_NONE && !in_progress) - die(_("No rebase in progress?")); + die(_("no rebase in progress")); if (options.action == ACTION_EDIT_TODO && !is_merge(&options)) die(_("The --edit-todo action can only be used during " diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 8c4f0cb90a..db65607485 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -22,7 +22,6 @@ #include "connected.h" #include "strvec.h" #include "version.h" -#include "tag.h" #include "gpg-interface.h" #include "sigchain.h" #include "fsck.h" @@ -142,6 +141,7 @@ static enum deny_action parse_deny_action(const char *var, const char *value) static int receive_pack_config(const char *var, const char *value, const struct config_context *ctx, void *cb) { + const char *msg_id; int status = parse_hide_refs_config(var, value, "receive", &hidden_refs); if (status) @@ -178,12 +178,14 @@ static int receive_pack_config(const char *var, const char *value, return 0; } - if (skip_prefix(var, "receive.fsck.", &var)) { - if (is_valid_msg_type(var, value)) + if (skip_prefix(var, "receive.fsck.", &msg_id)) { + if (!value) + return config_error_nonbool(var); + if (is_valid_msg_type(msg_id, value)) strbuf_addf(&fsck_msg_types, "%c%s=%s", - fsck_msg_types.len ? ',' : '=', var, value); + fsck_msg_types.len ? ',' : '=', msg_id, value); else - warning("skipping unknown msg id '%s'", var); + warning("skipping unknown msg id '%s'", msg_id); return 0; } @@ -591,21 +593,6 @@ static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp) return strbuf_detach(&buf, NULL); } -static char *find_header(const char *msg, size_t len, const char *key, - const char **next_line) -{ - size_t out_len; - const char *val = find_header_mem(msg, len, key, &out_len); - - if (!val) - return NULL; - - if (next_line) - *next_line = val + out_len + 1; - - return xmemdupz(val, out_len); -} - /* * Return zero if a and b are equal up to n bytes and nonzero if they are not. * This operation is guaranteed to run in constant time to avoid leaking data. @@ -620,13 +607,14 @@ static int constant_memequal(const char *a, const char *b, size_t n) return res; } -static const char *check_nonce(const char *buf, size_t len) +static const char *check_nonce(const char *buf) { - char *nonce = find_header(buf, len, "nonce", NULL); + size_t noncelen; + const char *found = find_commit_header(buf, "nonce", &noncelen); + char *nonce = found ? xmemdupz(found, noncelen) : NULL; timestamp_t stamp, ostamp; char *bohmac, *expect = NULL; const char *retval = NONCE_BAD; - size_t noncelen; if (!nonce) { retval = NONCE_MISSING; @@ -668,7 +656,6 @@ static const char *check_nonce(const char *buf, size_t len) goto leave; } - noncelen = strlen(nonce); expect = prepare_push_cert_nonce(service_dir, stamp); if (noncelen != strlen(expect)) { /* This is not even the right size. */ @@ -716,35 +703,28 @@ leave: static int check_cert_push_options(const struct string_list *push_options) { const char *buf = push_cert.buf; - int len = push_cert.len; - char *option; - const char *next_line; + const char *option; + size_t optionlen; int options_seen = 0; int retval = 1; - if (!len) + if (!*buf) return 1; - while ((option = find_header(buf, len, "push-option", &next_line))) { - len -= (next_line - buf); - buf = next_line; + while ((option = find_commit_header(buf, "push-option", &optionlen))) { + buf = option + optionlen + 1; options_seen++; if (options_seen > push_options->nr - || strcmp(option, - push_options->items[options_seen - 1].string)) { - retval = 0; - goto leave; - } - free(option); + || xstrncmpz(push_options->items[options_seen - 1].string, + option, optionlen)) + return 0; } if (options_seen != push_options->nr) retval = 0; -leave: - free(option); return retval; } @@ -771,7 +751,7 @@ static void prepare_push_cert_sha1(struct child_process *proc) check_signature(&sigcheck, push_cert.buf + bogs, push_cert.len - bogs); - nonce_status = check_nonce(push_cert.buf, bogs); + nonce_status = check_nonce(sigcheck.payload); } if (!is_null_oid(&push_cert_oid)) { strvec_pushf(&proc->env, "GIT_PUSH_CERT=%s", diff --git a/builtin/reflog.c b/builtin/reflog.c index 6e490f83d5..060eb3377e 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -7,11 +7,15 @@ #include "wildmatch.h" #include "worktree.h" #include "reflog.h" +#include "refs.h" #include "parse-options.h" #define BUILTIN_REFLOG_SHOW_USAGE \ N_("git reflog [show] [<log-options>] [<ref>]") +#define BUILTIN_REFLOG_LIST_USAGE \ + N_("git reflog list") + #define BUILTIN_REFLOG_EXPIRE_USAGE \ N_("git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" \ " [--rewrite] [--updateref] [--stale-fix]\n" \ @@ -29,6 +33,11 @@ static const char *const reflog_show_usage[] = { NULL, }; +static const char *const reflog_list_usage[] = { + BUILTIN_REFLOG_LIST_USAGE, + NULL, +}; + static const char *const reflog_expire_usage[] = { BUILTIN_REFLOG_EXPIRE_USAGE, NULL @@ -46,6 +55,7 @@ static const char *const reflog_exists_usage[] = { static const char *const reflog_usage[] = { BUILTIN_REFLOG_SHOW_USAGE, + BUILTIN_REFLOG_LIST_USAGE, BUILTIN_REFLOG_EXPIRE_USAGE, BUILTIN_REFLOG_DELETE_USAGE, BUILTIN_REFLOG_EXISTS_USAGE, @@ -60,8 +70,7 @@ struct worktree_reflogs { struct string_list reflogs; }; -static int collect_reflog(const char *ref, const struct object_id *oid UNUSED, - int flags UNUSED, void *cb_data) +static int collect_reflog(const char *ref, void *cb_data) { struct worktree_reflogs *cb = cb_data; struct worktree *worktree = cb->worktree; @@ -96,8 +105,7 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len) reflog_expire_cfg_tail = &reflog_expire_cfg; for (ent = reflog_expire_cfg; ent; ent = ent->next) - if (!strncmp(ent->pattern, pattern, len) && - ent->pattern[len] == '\0') + if (!xstrncmpz(ent->pattern, pattern, len)) return ent; FLEX_ALLOC_MEM(ent, pattern, pattern, len); @@ -239,6 +247,29 @@ static int cmd_reflog_show(int argc, const char **argv, const char *prefix) return cmd_log_reflog(argc, argv, prefix); } +static int show_reflog(const char *refname, void *cb_data UNUSED) +{ + printf("%s\n", refname); + return 0; +} + +static int cmd_reflog_list(int argc, const char **argv, const char *prefix) +{ + struct option options[] = { + OPT_END() + }; + struct ref_store *ref_store; + + argc = parse_options(argc, argv, prefix, options, reflog_list_usage, 0); + if (argc) + return error(_("%s does not accept arguments: '%s'"), + "list", argv[0]); + + ref_store = get_main_ref_store(the_repository); + + return refs_for_each_reflog(ref_store, show_reflog, NULL); +} + static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) { struct cmd_reflog_expire_cb cmd = { 0 }; @@ -248,7 +279,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) int verbose = 0; reflog_expiry_should_prune_fn *should_prune_fn = should_expire_reflog_ent; const struct option options[] = { - OPT_BIT(0, "dry-run", &flags, N_("do not actually prune any entries"), + OPT_BIT('n', "dry-run", &flags, N_("do not actually prune any entries"), EXPIRE_REFLOGS_DRY_RUN), OPT_BIT(0, "rewrite", &flags, N_("rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"), @@ -368,7 +399,7 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) int verbose = 0; const struct option options[] = { - OPT_BIT(0, "dry-run", &flags, N_("do not actually prune any entries"), + OPT_BIT('n', "dry-run", &flags, N_("do not actually prune any entries"), EXPIRE_REFLOGS_DRY_RUN), OPT_BIT(0, "rewrite", &flags, N_("rewrite the old SHA1 with the new SHA1 of the entry that now precedes it"), @@ -418,6 +449,7 @@ int cmd_reflog(int argc, const char **argv, const char *prefix) parse_opt_subcommand_fn *fn = NULL; struct option options[] = { OPT_SUBCOMMAND("show", &fn, cmd_reflog_show), + OPT_SUBCOMMAND("list", &fn, cmd_reflog_list), OPT_SUBCOMMAND("expire", &fn, cmd_reflog_expire), OPT_SUBCOMMAND("delete", &fn, cmd_reflog_delete), OPT_SUBCOMMAND("exists", &fn, cmd_reflog_exists), diff --git a/builtin/repack.c b/builtin/repack.c index edaee4dbec..ede36328a3 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -8,7 +8,6 @@ #include "path.h" #include "run-command.h" #include "server-info.h" -#include "sigchain.h" #include "strbuf.h" #include "string-list.h" #include "strvec.h" @@ -1203,19 +1202,13 @@ int cmd_repack(int argc, const char **argv, const char *prefix) if (delete_redundant && repository_format_precious_objects) die(_("cannot delete packs in a precious-objects repo")); - if (keep_unreachable && - (unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE))) - die(_("options '%s' and '%s' cannot be used together"), "--keep-unreachable", "-A"); + die_for_incompatible_opt3(unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE), "-A", + keep_unreachable, "-k/--keep-unreachable", + pack_everything & PACK_CRUFT, "--cruft"); - if (pack_everything & PACK_CRUFT) { + 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())) diff --git a/builtin/replay.c b/builtin/replay.c new file mode 100644 index 0000000000..6bc4b47f09 --- /dev/null +++ b/builtin/replay.c @@ -0,0 +1,446 @@ +/* + * "git replay" builtin command + */ + +#define USE_THE_INDEX_VARIABLE +#include "git-compat-util.h" + +#include "builtin.h" +#include "environment.h" +#include "hex.h" +#include "lockfile.h" +#include "merge-ort.h" +#include "object-name.h" +#include "parse-options.h" +#include "refs.h" +#include "revision.h" +#include "strmap.h" +#include <oidset.h> +#include <tree.h> + +static const char *short_commit_name(struct commit *commit) +{ + return repo_find_unique_abbrev(the_repository, &commit->object.oid, + DEFAULT_ABBREV); +} + +static struct commit *peel_committish(const char *name) +{ + struct object *obj; + struct object_id oid; + + if (repo_get_oid(the_repository, name, &oid)) + return NULL; + obj = parse_object(the_repository, &oid); + return (struct commit *)repo_peel_to_type(the_repository, name, 0, obj, + OBJ_COMMIT); +} + +static char *get_author(const char *message) +{ + size_t len; + const char *a; + + a = find_commit_header(message, "author", &len); + if (a) + return xmemdupz(a, len); + + return NULL; +} + +static struct commit *create_commit(struct tree *tree, + struct commit *based_on, + struct commit *parent) +{ + struct object_id ret; + struct object *obj; + struct commit_list *parents = NULL; + char *author; + char *sign_commit = NULL; /* FIXME: cli users might want to sign again */ + struct commit_extra_header *extra; + struct strbuf msg = STRBUF_INIT; + const char *out_enc = get_commit_output_encoding(); + const char *message = repo_logmsg_reencode(the_repository, based_on, + NULL, out_enc); + const char *orig_message = NULL; + const char *exclude_gpgsig[] = { "gpgsig", NULL }; + + commit_list_insert(parent, &parents); + extra = read_commit_extra_headers(based_on, exclude_gpgsig); + find_commit_subject(message, &orig_message); + strbuf_addstr(&msg, orig_message); + author = get_author(message); + reset_ident_date(); + if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents, + &ret, author, NULL, sign_commit, extra)) { + error(_("failed to write commit object")); + return NULL; + } + free(author); + strbuf_release(&msg); + + obj = parse_object(the_repository, &ret); + return (struct commit *)obj; +} + +struct ref_info { + struct commit *onto; + struct strset positive_refs; + struct strset negative_refs; + int positive_refexprs; + int negative_refexprs; +}; + +static void get_ref_information(struct rev_cmdline_info *cmd_info, + struct ref_info *ref_info) +{ + int i; + + ref_info->onto = NULL; + strset_init(&ref_info->positive_refs); + strset_init(&ref_info->negative_refs); + ref_info->positive_refexprs = 0; + ref_info->negative_refexprs = 0; + + /* + * When the user specifies e.g. + * git replay origin/main..mybranch + * git replay ^origin/next mybranch1 mybranch2 + * we want to be able to determine where to replay the commits. In + * these examples, the branches are probably based on an old version + * of either origin/main or origin/next, so we want to replay on the + * newest version of that branch. In contrast we would want to error + * out if they ran + * git replay ^origin/master ^origin/next mybranch + * git replay mybranch~2..mybranch + * the first of those because there's no unique base to choose, and + * the second because they'd likely just be replaying commits on top + * of the same commit and not making any difference. + */ + for (i = 0; i < cmd_info->nr; i++) { + struct rev_cmdline_entry *e = cmd_info->rev + i; + struct object_id oid; + const char *refexpr = e->name; + char *fullname = NULL; + int can_uniquely_dwim = 1; + + if (*refexpr == '^') + refexpr++; + if (repo_dwim_ref(the_repository, refexpr, strlen(refexpr), &oid, &fullname, 0) != 1) + can_uniquely_dwim = 0; + + if (e->flags & BOTTOM) { + if (can_uniquely_dwim) + strset_add(&ref_info->negative_refs, fullname); + if (!ref_info->negative_refexprs) + ref_info->onto = lookup_commit_reference_gently(the_repository, + &e->item->oid, 1); + ref_info->negative_refexprs++; + } else { + if (can_uniquely_dwim) + strset_add(&ref_info->positive_refs, fullname); + ref_info->positive_refexprs++; + } + + free(fullname); + } +} + +static void determine_replay_mode(struct rev_cmdline_info *cmd_info, + const char *onto_name, + const char **advance_name, + struct commit **onto, + struct strset **update_refs) +{ + struct ref_info rinfo; + + get_ref_information(cmd_info, &rinfo); + if (!rinfo.positive_refexprs) + die(_("need some commits to replay")); + if (onto_name && *advance_name) + die(_("--onto and --advance are incompatible")); + else if (onto_name) { + *onto = peel_committish(onto_name); + if (rinfo.positive_refexprs < + strset_get_size(&rinfo.positive_refs)) + die(_("all positive revisions given must be references")); + } else if (*advance_name) { + struct object_id oid; + char *fullname = NULL; + + *onto = peel_committish(*advance_name); + if (repo_dwim_ref(the_repository, *advance_name, strlen(*advance_name), + &oid, &fullname, 0) == 1) { + *advance_name = fullname; + } else { + die(_("argument to --advance must be a reference")); + } + if (rinfo.positive_refexprs > 1) + die(_("cannot advance target with multiple sources because ordering would be ill-defined")); + } else { + int positive_refs_complete = ( + rinfo.positive_refexprs == + strset_get_size(&rinfo.positive_refs)); + int negative_refs_complete = ( + rinfo.negative_refexprs == + strset_get_size(&rinfo.negative_refs)); + /* + * We need either positive_refs_complete or + * negative_refs_complete, but not both. + */ + if (rinfo.negative_refexprs > 0 && + positive_refs_complete == negative_refs_complete) + die(_("cannot implicitly determine whether this is an --advance or --onto operation")); + if (negative_refs_complete) { + struct hashmap_iter iter; + struct strmap_entry *entry; + + if (rinfo.negative_refexprs == 0) + die(_("all positive revisions given must be references")); + else if (rinfo.negative_refexprs > 1) + die(_("cannot implicitly determine whether this is an --advance or --onto operation")); + else if (rinfo.positive_refexprs > 1) + die(_("cannot advance target with multiple source branches because ordering would be ill-defined")); + + /* Only one entry, but we have to loop to get it */ + strset_for_each_entry(&rinfo.negative_refs, + &iter, entry) { + *advance_name = entry->key; + } + } else { /* positive_refs_complete */ + if (rinfo.negative_refexprs > 1) + die(_("cannot implicitly determine correct base for --onto")); + if (rinfo.negative_refexprs == 1) + *onto = rinfo.onto; + } + } + if (!*advance_name) { + *update_refs = xcalloc(1, sizeof(**update_refs)); + **update_refs = rinfo.positive_refs; + memset(&rinfo.positive_refs, 0, sizeof(**update_refs)); + } + strset_clear(&rinfo.negative_refs); + strset_clear(&rinfo.positive_refs); +} + +static struct commit *mapped_commit(kh_oid_map_t *replayed_commits, + struct commit *commit, + struct commit *fallback) +{ + khint_t pos = kh_get_oid_map(replayed_commits, commit->object.oid); + if (pos == kh_end(replayed_commits)) + return fallback; + return kh_value(replayed_commits, pos); +} + +static struct commit *pick_regular_commit(struct commit *pickme, + kh_oid_map_t *replayed_commits, + struct commit *onto, + struct merge_options *merge_opt, + struct merge_result *result) +{ + struct commit *base, *replayed_base; + struct tree *pickme_tree, *base_tree; + + base = pickme->parents->item; + replayed_base = mapped_commit(replayed_commits, base, onto); + + result->tree = repo_get_commit_tree(the_repository, replayed_base); + pickme_tree = repo_get_commit_tree(the_repository, pickme); + base_tree = repo_get_commit_tree(the_repository, base); + + merge_opt->branch1 = short_commit_name(replayed_base); + merge_opt->branch2 = short_commit_name(pickme); + merge_opt->ancestor = xstrfmt("parent of %s", merge_opt->branch2); + + merge_incore_nonrecursive(merge_opt, + base_tree, + result->tree, + pickme_tree, + result); + + free((char*)merge_opt->ancestor); + merge_opt->ancestor = NULL; + if (!result->clean) + return NULL; + return create_commit(result->tree, pickme, replayed_base); +} + +int cmd_replay(int argc, const char **argv, const char *prefix) +{ + const char *advance_name = NULL; + struct commit *onto = NULL; + const char *onto_name = NULL; + int contained = 0; + + struct rev_info revs; + struct commit *last_commit = NULL; + struct commit *commit; + struct merge_options merge_opt; + struct merge_result result; + struct strset *update_refs = NULL; + kh_oid_map_t *replayed_commits; + int ret = 0; + + const char * const replay_usage[] = { + N_("(EXPERIMENTAL!) git replay " + "([--contained] --onto <newbase> | --advance <branch>) " + "<revision-range>..."), + NULL + }; + struct option replay_options[] = { + OPT_STRING(0, "advance", &advance_name, + N_("branch"), + N_("make replay advance given branch")), + OPT_STRING(0, "onto", &onto_name, + N_("revision"), + N_("replay onto given commit")), + OPT_BOOL(0, "contained", &contained, + N_("advance all branches contained in revision-range")), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, replay_options, replay_usage, + PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); + + if (!onto_name && !advance_name) { + error(_("option --onto or --advance is mandatory")); + usage_with_options(replay_usage, replay_options); + } + + if (advance_name && contained) + die(_("options '%s' and '%s' cannot be used together"), + "--advance", "--contained"); + + repo_init_revisions(the_repository, &revs, prefix); + + /* + * Set desired values for rev walking options here. If they + * are changed by some user specified option in setup_revisions() + * below, we will detect that below and then warn. + * + * TODO: In the future we might want to either die(), or allow + * some options changing these values if we think they could + * be useful. + */ + revs.reverse = 1; + revs.sort_order = REV_SORT_IN_GRAPH_ORDER; + revs.topo_order = 1; + revs.simplify_history = 0; + + argc = setup_revisions(argc, argv, &revs, NULL); + if (argc > 1) { + ret = error(_("unrecognized argument: %s"), argv[1]); + goto cleanup; + } + + /* + * Detect and warn if we override some user specified rev + * walking options. + */ + if (revs.reverse != 1) { + warning(_("some rev walking options will be overridden as " + "'%s' bit in 'struct rev_info' will be forced"), + "reverse"); + revs.reverse = 1; + } + if (revs.sort_order != REV_SORT_IN_GRAPH_ORDER) { + warning(_("some rev walking options will be overridden as " + "'%s' bit in 'struct rev_info' will be forced"), + "sort_order"); + revs.sort_order = REV_SORT_IN_GRAPH_ORDER; + } + if (revs.topo_order != 1) { + warning(_("some rev walking options will be overridden as " + "'%s' bit in 'struct rev_info' will be forced"), + "topo_order"); + revs.topo_order = 1; + } + if (revs.simplify_history != 0) { + warning(_("some rev walking options will be overridden as " + "'%s' bit in 'struct rev_info' will be forced"), + "simplify_history"); + revs.simplify_history = 0; + } + + determine_replay_mode(&revs.cmdline, onto_name, &advance_name, + &onto, &update_refs); + + if (!onto) /* FIXME: Should handle replaying down to root commit */ + die("Replaying down to root commit is not supported yet!"); + + 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)); + merge_opt.show_rename_progress = 0; + last_commit = onto; + replayed_commits = kh_init_oid_map(); + while ((commit = get_revision(&revs))) { + const struct name_decoration *decoration; + khint_t pos; + int hr; + + if (!commit->parents) + die(_("replaying down to root commit is not supported yet!")); + if (commit->parents->next) + die(_("replaying merge commits is not supported yet!")); + + last_commit = pick_regular_commit(commit, replayed_commits, onto, + &merge_opt, &result); + if (!last_commit) + break; + + /* Record commit -> last_commit mapping */ + pos = kh_put_oid_map(replayed_commits, commit->object.oid, &hr); + if (hr == 0) + BUG("Duplicate rewritten commit: %s\n", + oid_to_hex(&commit->object.oid)); + kh_value(replayed_commits, pos) = last_commit; + + /* Update any necessary branches */ + if (advance_name) + continue; + decoration = get_name_decoration(&commit->object); + if (!decoration) + continue; + while (decoration) { + if (decoration->type == DECORATION_REF_LOCAL && + (contained || strset_contains(update_refs, + decoration->name))) { + printf("update %s %s %s\n", + decoration->name, + oid_to_hex(&last_commit->object.oid), + oid_to_hex(&commit->object.oid)); + } + decoration = decoration->next; + } + } + + /* In --advance mode, advance the target ref */ + if (result.clean == 1 && advance_name) { + printf("update %s %s %s\n", + advance_name, + oid_to_hex(&last_commit->object.oid), + oid_to_hex(&onto->object.oid)); + } + + merge_finalize(&merge_opt, &result); + kh_destroy_oid_map(replayed_commits); + if (update_refs) { + strset_clear(update_refs); + free(update_refs); + } + ret = result.clean; + +cleanup: + release_revisions(&revs); + + /* Return */ + if (ret < 0) + exit(128); + return ret ? 0 : 1; +} diff --git a/builtin/rerere.c b/builtin/rerere.c index 07a9d37275..b2efc6f640 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -1,6 +1,5 @@ #include "builtin.h" #include "config.h" -#include "dir.h" #include "gettext.h" #include "parse-options.h" #include "repository.h" diff --git a/builtin/reset.c b/builtin/reset.c index 4b018d20e3..f0bf29a478 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -16,10 +16,8 @@ #include "hash.h" #include "hex.h" #include "lockfile.h" -#include "tag.h" #include "object.h" #include "pretty.h" -#include "run-command.h" #include "refs.h" #include "diff.h" #include "diffcore.h" @@ -33,7 +31,6 @@ #include "setup.h" #include "sparse-index.h" #include "submodule.h" -#include "submodule-config.h" #include "trace.h" #include "trace2.h" #include "dir.h" @@ -284,7 +281,9 @@ static void parse_args(struct pathspec *pathspec, verify_filename(prefix, argv[0], 1); } } - *rev_ret = rev; + + /* treat '@' as a shortcut for 'HEAD' */ + *rev_ret = !strcmp("@", rev) ? "HEAD" : rev; parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL | diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 181353dcf5..b3f4783858 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -7,13 +7,11 @@ #include "hex.h" #include "revision.h" #include "list-objects.h" -#include "list-objects-filter.h" #include "list-objects-filter-options.h" #include "object.h" #include "object-name.h" #include "object-file.h" #include "object-store-ll.h" -#include "pack.h" #include "pack-bitmap.h" #include "log-tree.h" #include "graph.h" diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index fde8861ca4..d08987646a 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -893,13 +893,15 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) } if (opt_with_value(arg, "--branches", &arg)) { if (ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --branches")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--branches"); handle_ref_opt(arg, "refs/heads/"); continue; } if (opt_with_value(arg, "--tags", &arg)) { if (ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --tags")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--tags"); handle_ref_opt(arg, "refs/tags/"); continue; } @@ -909,7 +911,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) } if (opt_with_value(arg, "--remotes", &arg)) { if (ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --remotes")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--remotes"); handle_ref_opt(arg, "refs/remotes/"); continue; } @@ -1059,6 +1062,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) puts(the_hash_algo->name); continue; } + if (!strcmp(arg, "--show-ref-format")) { + puts(ref_storage_format_to_name(the_repository->ref_storage_format)); + continue; + } if (!strcmp(arg, "--end-of-options")) { seen_end_of_options = 1; if (filter & (DO_FLAGS | DO_REVS)) diff --git a/builtin/revert.c b/builtin/revert.c index e6f9a1ad26..89821bab95 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -1,5 +1,4 @@ #include "git-compat-util.h" -#include "config.h" #include "builtin.h" #include "parse-options.h" #include "diff.h" @@ -7,7 +6,6 @@ #include "repository.h" #include "revision.h" #include "rerere.h" -#include "dir.h" #include "sequencer.h" #include "branch.h" diff --git a/builtin/rm.c b/builtin/rm.c index dff819ae50..fd130cea2d 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -9,7 +9,6 @@ #include "config.h" #include "lockfile.h" #include "dir.h" -#include "cache-tree.h" #include "gettext.h" #include "hash.h" #include "tree-walk.h" diff --git a/builtin/send-pack.c b/builtin/send-pack.c index cd6d9e4112..3df9eaad09 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -1,19 +1,14 @@ #include "builtin.h" #include "config.h" -#include "commit.h" #include "hex.h" -#include "refs.h" #include "pkt-line.h" -#include "sideband.h" #include "run-command.h" #include "remote.h" #include "connect.h" #include "send-pack.h" #include "quote.h" #include "transport.h" -#include "version.h" #include "oid-array.h" -#include "gpg-interface.h" #include "gettext.h" #include "protocol.h" #include "parse-options.h" @@ -135,21 +130,18 @@ static int send_pack_config(const char *k, const char *v, const struct config_context *ctx, void *cb) { if (!strcmp(k, "push.gpgsign")) { - const char *value; - if (!git_config_get_value("push.gpgsign", &value)) { - switch (git_parse_maybe_bool(value)) { - case 0: - args.push_cert = SEND_PACK_PUSH_CERT_NEVER; - break; - case 1: - args.push_cert = SEND_PACK_PUSH_CERT_ALWAYS; - break; - default: - if (value && !strcasecmp(value, "if-asked")) - args.push_cert = SEND_PACK_PUSH_CERT_IF_ASKED; - else - return error(_("invalid value for '%s'"), k); - } + switch (git_parse_maybe_bool(v)) { + case 0: + args.push_cert = SEND_PACK_PUSH_CERT_NEVER; + break; + case 1: + args.push_cert = SEND_PACK_PUSH_CERT_ALWAYS; + break; + default: + if (!strcasecmp(v, "if-asked")) + args.push_cert = SEND_PACK_PUSH_CERT_IF_ASKED; + else + return error(_("invalid value for '%s'"), k); } } return git_default_config(k, v, ctx, cb); @@ -208,7 +200,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "stateless-rpc", &stateless_rpc, N_("use stateless RPC protocol")), OPT_BOOL(0, "stdin", &from_stdin, N_("read refs from stdin")), OPT_BOOL(0, "helper-status", &helper_status, N_("print status from remote helper")), - OPT_CALLBACK_F(0, CAS_OPT_NAME, &cas, N_("<refname>:<expect>"), + OPT_CALLBACK_F(0, "force-with-lease", &cas, N_("<refname>:<expect>"), N_("require old value of ref to be at this value"), PARSE_OPT_OPTARG, parseopt_push_cas_option), OPT_BOOL(0, TRANS_OPT_FORCE_IF_INCLUDES, &force_if_includes, @@ -341,6 +333,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) } if (!ret && !transport_refs_pushed(remote_refs)) + /* stable plumbing output; do not modify or localize */ fprintf(stderr, "Everything up-to-date\n"); return ret; diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 7aac525a87..1c15421e60 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -6,7 +6,6 @@ #include "object-name.h" #include "object-store-ll.h" #include "object.h" -#include "tag.h" #include "string-list.h" #include "parse-options.h" @@ -173,7 +172,7 @@ static int cmd_show_ref__verify(const struct show_one_options *show_one_opts, while (*refs) { struct object_id oid; - if ((starts_with(*refs, "refs/") || !strcmp(*refs, "HEAD")) && + if ((starts_with(*refs, "refs/") || refname_is_safe(*refs)) && !read_ref(*refs, &oid)) { show_one(show_one_opts, *refs, &oid); } @@ -239,7 +238,7 @@ static int cmd_show_ref__exists(const char **refs) if (refs_read_raw_ref(get_main_ref_store(the_repository), ref, &unused_oid, &unused_referent, &unused_type, &failure_errno)) { - if (failure_errno == ENOENT) { + if (failure_errno == ENOENT || failure_errno == EISDIR) { error(_("reference does not exist")); ret = 2; } else { @@ -315,9 +314,9 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, show_ref_options, show_ref_usage, 0); - if ((!!exclude_existing_opts.enabled + !!verify + !!exists) > 1) - die(_("only one of '%s', '%s' or '%s' can be given"), - "--exclude-existing", "--verify", "--exists"); + die_for_incompatible_opt3(exclude_existing_opts.enabled, "--exclude-existing", + verify, "--verify", + exists, "--exists"); if (exclude_existing_opts.enabled) return cmd_show_ref__exclude_existing(&exclude_existing_opts); diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 5c8ffb1f75..0f52e25249 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -8,14 +8,10 @@ #include "parse-options.h" #include "pathspec.h" #include "repository.h" -#include "run-command.h" #include "strbuf.h" #include "string-list.h" -#include "cache-tree.h" #include "lockfile.h" -#include "resolve-undo.h" #include "unpack-trees.h" -#include "wt-status.h" #include "quote.h" #include "setup.h" #include "sparse-index.h" @@ -777,8 +773,7 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, builtin_sparse_checkout_add_options, - builtin_sparse_checkout_add_usage, - PARSE_OPT_KEEP_UNKNOWN_OPT); + builtin_sparse_checkout_add_usage, 0); sanitize_paths(argc, argv, prefix, add_opts.skip_checks); @@ -824,8 +819,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, builtin_sparse_checkout_set_options, - builtin_sparse_checkout_set_usage, - PARSE_OPT_KEEP_UNKNOWN_OPT); + builtin_sparse_checkout_set_usage, 0); if (update_modes(&set_opts.cone_mode, &set_opts.sparse_index)) return 1; @@ -835,7 +829,7 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) * non-cone mode, if nothing is specified, manually select just the * top-level directory (much as 'init' would do). */ - if (!core_sparse_checkout_cone && argc == 0) { + if (!core_sparse_checkout_cone && !set_opts.use_stdin && argc == 0) { argv = default_patterns; argc = default_patterns_nr; } else { @@ -996,8 +990,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char * argc = parse_options(argc, argv, prefix, builtin_sparse_checkout_check_rules_options, - builtin_sparse_checkout_check_rules_usage, - PARSE_OPT_KEEP_UNKNOWN_OPT); + builtin_sparse_checkout_check_rules_usage, 0); if (check_rules_opts.rules_file && check_rules_opts.cone_mode < 0) check_rules_opts.cone_mode = 1; diff --git a/builtin/stash.c b/builtin/stash.c index 4a6771c9f4..7fb355bff0 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -26,7 +26,6 @@ #include "sparse-index.h" #include "log-tree.h" #include "diffcore.h" -#include "exec-cmd.h" #include "reflog.h" #include "add-interactive.h" @@ -521,7 +520,7 @@ static void unstage_changes_unless_new(struct object_id *orig_tree) repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR); if (write_locked_index(&the_index, &lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) - die(_("Unable to write index.")); + die(_("could not write index")); } static int do_apply_stash(const char *prefix, struct stash_info *info, @@ -538,7 +537,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, repo_read_index_preload(the_repository, NULL, 0); if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0, NULL, NULL, NULL)) - return -1; + return error(_("could not write index")); if (write_index_as_tree(&c_tree, &the_index, get_index_file(), 0, NULL)) @@ -1365,7 +1364,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b repo_read_index_preload(the_repository, NULL, 0); if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0, NULL, NULL, NULL) < 0) { - ret = -1; + ret = error(_("could not write index")); goto done; } @@ -1556,7 +1555,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET, 0, 0, NULL, NULL, NULL)) { - ret = -1; + ret = error(_("could not write index")); goto done; } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index cce46450ab..fda50f2af1 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -22,7 +22,6 @@ #include "remote.h" #include "refs.h" #include "refspec.h" -#include "connect.h" #include "revision.h" #include "diffcore.h" #include "diff.h" diff --git a/builtin/tag.c b/builtin/tag.c index 3918eacbb5..19a7e06bf4 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -18,7 +18,6 @@ #include "object-store-ll.h" #include "path.h" #include "tag.h" -#include "run-command.h" #include "parse-options.h" #include "diff.h" #include "revision.h" @@ -44,18 +43,11 @@ static const char * const git_tag_usage[] = { static unsigned int colopts; static int force_sign_annotate; static int config_sign_tag = -1; /* unspecified */ -static int omit_empty = 0; static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, struct ref_format *format) { - struct ref_array array; - struct strbuf output = STRBUF_INIT; - struct strbuf err = STRBUF_INIT; char *to_free = NULL; - int i; - - memset(&array, 0, sizeof(array)); if (filter->lines == -1) filter->lines = 0; @@ -73,23 +65,8 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, if (verify_ref_format(format)) die(_("unable to parse format string")); filter->with_commit_tag_algo = 1; - filter_refs(&array, filter, FILTER_REFS_TAGS); - filter_ahead_behind(the_repository, format, &array); - ref_array_sort(sorting, &array); - - for (i = 0; i < array.nr; i++) { - strbuf_reset(&output); - strbuf_reset(&err); - if (format_ref_array_item(array.items[i], format, &output, &err)) - die("%s", err.buf); - fwrite(output.buf, 1, output.len, stdout); - if (output.len || !omit_empty) - putchar('\n'); - } + filter_and_format_refs(filter, FILTER_REFS_TAGS, sorting, format); - strbuf_release(&err); - strbuf_release(&output); - ref_array_clear(&array); free(to_free); return 0; @@ -176,7 +153,7 @@ static int verify_tag(const char *name, const char *ref UNUSED, static int do_sign(struct strbuf *buffer) { - return sign_buffer(buffer, buffer, get_signing_key()); + return sign_buffer(buffer, buffer, get_signing_key()) ? -1 : 0; } static const char tag_template[] = @@ -481,7 +458,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_WITHOUT(&filter.no_commit, N_("print only tags that don't contain the commit")), OPT_MERGED(&filter, N_("print only tags that are merged")), OPT_NO_MERGED(&filter, N_("print only tags that are not merged")), - OPT_BOOL(0, "omit-empty", &omit_empty, + OPT_BOOL(0, "omit-empty", &format.array_opts.omit_empty, N_("do not output a newline after empty formatted refs")), OPT_REF_SORT(&sorting_options), { @@ -501,7 +478,13 @@ int cmd_tag(int argc, const char **argv, const char *prefix) setup_ref_filter_porcelain_msg(); + /* + * Try to set sort keys from config. If config does not set any, + * fall back on default (refname) sorting. + */ git_config(git_tag_config, &sorting_options); + if (!sorting_options.nr) + string_list_append(&sorting_options, "refname"); memset(&opt, 0, sizeof(opt)); filter.lines = -1; @@ -547,7 +530,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix) struct column_options copts; memset(&copts, 0, sizeof(copts)); copts.padding = 2; - run_column_filter(colopts, &copts); + if (run_column_filter(colopts, &copts)) + die(_("could not start 'git column'")); } filter.name_patterns = argv; ret = list_tags(&filter, sorting, &format); diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index fef7423448..e0a701f2b3 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -10,12 +10,8 @@ #include "delta.h" #include "pack.h" #include "blob.h" -#include "commit.h" #include "replace-object.h" #include "strbuf.h" -#include "tag.h" -#include "tree.h" -#include "tree-walk.h" #include "progress.h" #include "decorate.h" #include "fsck.h" diff --git a/builtin/update-ref.c b/builtin/update-ref.c index c0c4e65e6f..61338a01ec 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -7,7 +7,6 @@ #include "parse-options.h" #include "quote.h" #include "repository.h" -#include "strvec.h" static const char * const git_update_ref_usage[] = { N_("git update-ref [<options>] -d <refname> [<old-val>]"), diff --git a/builtin/var.c b/builtin/var.c index 8cf7dd9e2e..cf5567208a 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -90,7 +90,7 @@ static char *git_config_val_global(int ident_flag UNUSED) char *user, *xdg; size_t unused; - git_global_config(&user, &xdg); + git_global_config_paths(&user, &xdg); if (xdg && *xdg) { normalize_path_copy(xdg, xdg); strbuf_addf(&buf, "%s\n", xdg); diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c index 9680b58701..0d2b9aea2a 100644 --- a/builtin/verify-commit.c +++ b/builtin/verify-commit.c @@ -9,10 +9,8 @@ #include "config.h" #include "gettext.h" #include "object-name.h" -#include "object-store-ll.h" #include "repository.h" #include "commit.h" -#include "run-command.h" #include "parse-options.h" #include "gpg-interface.h" diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index d8753270eb..c731e2f87b 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -9,7 +9,6 @@ #include "config.h" #include "gettext.h" #include "tag.h" -#include "run-command.h" #include "object-name.h" #include "parse-options.h" #include "gpg-interface.h" diff --git a/builtin/worktree.c b/builtin/worktree.c index 62b7e26f4b..9c76b62b02 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -49,14 +49,14 @@ _("No possible source branch, inferring '--orphan'") #define WORKTREE_ADD_ORPHAN_WITH_DASH_B_HINT_TEXT \ - _("If you meant to create a worktree containing a new orphan branch\n" \ + _("If you meant to create a worktree containing a new unborn branch\n" \ "(branch with no commits) for this repository, you can do so\n" \ "using the --orphan flag:\n" \ "\n" \ " git worktree add --orphan -b %s %s\n") #define WORKTREE_ADD_ORPHAN_NO_DASH_B_HINT_TEXT \ - _("If you meant to create a worktree containing a new orphan branch\n" \ + _("If you meant to create a worktree containing a new unborn branch\n" \ "(branch with no commits) for this repository, you can do so\n" \ "using the --orphan flag:\n" \ "\n" \ @@ -416,7 +416,6 @@ static int add_worktree(const char *path, const char *refname, struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT; struct strbuf sb = STRBUF_INIT, realpath = STRBUF_INIT; const char *name; - struct child_process cp = CHILD_PROCESS_INIT; struct strvec child_env = STRVEC_INIT; unsigned int counter = 0; int len, ret; @@ -424,7 +423,8 @@ static int add_worktree(const char *path, const char *refname, struct commit *commit = NULL; int is_branch = 0; struct strbuf sb_name = STRBUF_INIT; - struct worktree **worktrees; + struct worktree **worktrees, *wt = NULL; + struct ref_store *wt_refs; worktrees = get_worktrees(); check_candidate_path(path, opts->force, worktrees, "add"); @@ -495,21 +495,33 @@ static int add_worktree(const char *path, const char *refname, strbuf_realpath(&realpath, get_git_common_dir(), 1); write_file(sb_git.buf, "gitdir: %s/worktrees/%s", realpath.buf, name); - /* - * This is to keep resolve_ref() happy. We need a valid HEAD - * or is_git_directory() will reject the directory. Any value which - * looks like an object ID will do since it will be immediately - * replaced by the symbolic-ref or update-ref invocation in the new - * worktree. - */ - strbuf_reset(&sb); - strbuf_addf(&sb, "%s/HEAD", sb_repo.buf); - write_file(sb.buf, "%s", oid_to_hex(null_oid())); strbuf_reset(&sb); strbuf_addf(&sb, "%s/commondir", sb_repo.buf); write_file(sb.buf, "../.."); /* + * Set up the ref store of the worktree and create the HEAD reference. + */ + wt = get_linked_worktree(name, 1); + if (!wt) { + ret = error(_("could not find created worktree '%s'"), name); + goto done; + } + wt_refs = get_worktree_ref_store(wt); + + ret = refs_init_db(wt_refs, REFS_INIT_DB_IS_WORKTREE, &sb); + if (ret) + goto done; + + if (!is_branch && commit) + ret = refs_update_ref(wt_refs, NULL, "HEAD", &commit->object.oid, + NULL, 0, UPDATE_REFS_MSG_ON_ERR); + else + ret = refs_create_symref(wt_refs, "HEAD", symref.buf, NULL); + if (ret) + goto done; + + /* * If the current worktree has sparse-checkout enabled, then copy * the sparse-checkout patterns from the current worktree. */ @@ -526,22 +538,6 @@ static int add_worktree(const char *path, const char *refname, strvec_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf); strvec_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path); - cp.git_cmd = 1; - - if (!is_branch && commit) { - strvec_pushl(&cp.args, "update-ref", "HEAD", - oid_to_hex(&commit->object.oid), NULL); - } else { - strvec_pushl(&cp.args, "symbolic-ref", "HEAD", - symref.buf, NULL); - if (opts->quiet) - strvec_push(&cp.args, "--quiet"); - } - - strvec_pushv(&cp.env, child_env.v); - ret = run_command(&cp); - if (ret) - goto done; if (opts->orphan && (ret = make_worktree_orphan(refname, opts, &child_env))) @@ -587,6 +583,7 @@ done: strbuf_release(&sb_git); strbuf_release(&sb_name); strbuf_release(&realpath); + free_worktree(wt); return ret; } @@ -730,11 +727,11 @@ static int dwim_orphan(const struct add_opts *opts, int opt_track, int remote) } if (opt_track) { - die(_("'%s' and '%s' cannot be used together"), "--orphan", - "--track"); + die(_("options '%s' and '%s' cannot be used together"), + "--orphan", "--track"); } else if (!opts->checkout) { - die(_("'%s' and '%s' cannot be used together"), "--orphan", - "--no-checkout"); + die(_("options '%s' and '%s' cannot be used together"), + "--orphan", "--no-checkout"); } return 1; } @@ -784,7 +781,7 @@ static int add(int ac, const char **av, const char *prefix) N_("create a new branch")), OPT_STRING('B', NULL, &new_branch_force, N_("branch"), N_("create or reset a branch")), - OPT_BOOL(0, "orphan", &opts.orphan, N_("create unborn/orphaned branch")), + OPT_BOOL(0, "orphan", &opts.orphan, N_("create unborn branch")), OPT_BOOL('d', "detach", &opts.detach, N_("detach HEAD at named commit")), OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")), OPT_BOOL(0, "lock", &keep_locked, N_("keep the new working tree locked")), @@ -806,16 +803,17 @@ static int add(int ac, const char **av, const char *prefix) if (!!opts.detach + !!new_branch + !!new_branch_force > 1) die(_("options '%s', '%s', and '%s' cannot be used together"), "-b", "-B", "--detach"); if (opts.detach && opts.orphan) - die(_("options '%s', and '%s' cannot be used together"), + die(_("options '%s' and '%s' cannot be used together"), "--orphan", "--detach"); if (opts.orphan && opt_track) - die(_("'%s' and '%s' cannot be used together"), "--orphan", "--track"); + die(_("options '%s' and '%s' cannot be used together"), + "--orphan", "--track"); if (opts.orphan && !opts.checkout) - die(_("'%s' and '%s' cannot be used together"), "--orphan", - "--no-checkout"); + die(_("options '%s' and '%s' cannot be used together"), + "--orphan", "--no-checkout"); if (opts.orphan && ac == 2) - die(_("'%s' and '%s' cannot be used together"), "--orphan", - _("<commit-ish>")); + die(_("option '%s' and commit-ish cannot be used together"), + "--orphan"); if (lock_reason && !keep_locked) die(_("the option '%s' requires '%s'"), "--reason", "--lock"); if (lock_reason) @@ -850,21 +848,21 @@ static int add(int ac, const char **av, const char *prefix) const char *s = worktree_basename(path, &n); new_branch = xstrndup(s, n); } else if (opts.orphan) { - // No-op + ; /* no-op */ } else if (opts.detach) { - // Check HEAD + /* Check HEAD */ if (!strcmp(branch, "HEAD")) can_use_local_refs(&opts); } else if (ac < 2 && new_branch) { - // DWIM: Infer --orphan when repo has no refs. + /* DWIM: Infer --orphan when repo has no refs. */ opts.orphan = dwim_orphan(&opts, !!opt_track, 0); } else if (ac < 2) { - // DWIM: Guess branch name from path. + /* DWIM: Guess branch name from path. */ const char *s = dwim_branch(path, &new_branch); if (s) branch = s; - // DWIM: Infer --orphan when repo has no refs. + /* DWIM: Infer --orphan when repo has no refs. */ opts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1); } else if (ac == 2) { struct object_id oid; diff --git a/bulk-checkin.c b/bulk-checkin.c index 6ce62999e5..eb46b88637 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -11,7 +11,6 @@ #include "csum-file.h" #include "pack.h" #include "strbuf.h" -#include "string-list.h" #include "tmp-objdir.h" #include "packfile.h" #include "object-file.h" diff --git a/bundle-uri.c b/bundle-uri.c index 8492fffd2f..ca32050a78 100644 --- a/bundle-uri.c +++ b/bundle-uri.c @@ -4,7 +4,6 @@ #include "copy.h" #include "environment.h" #include "gettext.h" -#include "object-store-ll.h" #include "refs.h" #include "run-command.h" #include "hashmap.h" diff --git a/cache-tree.c b/cache-tree.c index 641427ed41..64678fe199 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -11,7 +11,6 @@ #include "read-cache-ll.h" #include "replace-object.h" #include "promisor-remote.h" -#include "sparse-index.h" #include "trace.h" #include "trace2.h" diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 4f407530d3..b4e22de3cb 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -37,15 +37,13 @@ macos-*) test -z "$BREW_INSTALL_PACKAGES" || brew install $BREW_INSTALL_PACKAGES brew link --force gettext - mkdir -p $HOME/bin - ( - cd $HOME/bin + + mkdir -p "$P4_PATH" + pushd "$P4_PATH" wget -q "$P4WHENCE/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 + popd if test -n "$CC_PACKAGE" then diff --git a/ci/install-docker-dependencies.sh b/ci/install-docker-dependencies.sh index 78b7e326da..eb2c9e1eca 100755 --- a/ci/install-docker-dependencies.sh +++ b/ci/install-docker-dependencies.sh @@ -3,6 +3,10 @@ # Install dependencies required to build and test Git inside container # +. ${0%/*}/lib.sh + +begin_group "Install dependencies" + case "$jobname" in linux32) linux32 --32bit i386 sh -c ' @@ -12,11 +16,31 @@ linux32) ' ;; linux-musl) - apk add --update build-base curl-dev openssl-dev expat-dev gettext \ - pcre2-dev python3 musl-libintl perl-utils ncurses >/dev/null + apk add --update shadow sudo build-base curl-dev openssl-dev expat-dev gettext \ + pcre2-dev python3 musl-libintl perl-utils ncurses \ + apache2 apache2-http2 apache2-proxy apache2-ssl apache2-webdav apr-util-dbd_sqlite3 \ + bash cvs gnupg perl-cgi perl-dbd-sqlite >/dev/null + ;; +linux-*|StaticAnalysis) + # Required so that apt doesn't wait for user input on certain packages. + export DEBIAN_FRONTEND=noninteractive + + apt update -q && + apt install -q -y sudo git make language-pack-is libsvn-perl apache2 libssl-dev \ + libcurl4-openssl-dev libexpat-dev tcl tk gettext zlib1g-dev \ + perl-modules liberror-perl libauthen-sasl-perl libemail-valid-perl \ + libdbd-sqlite3-perl libio-socket-ssl-perl libnet-smtp-ssl-perl ${CC_PACKAGE:-${CC:-gcc}} \ + apache2 cvs cvsps gnupg libcgi-pm-perl subversion + + if test "$jobname" = StaticAnalysis + then + apt install -q -y coccinelle + fi ;; pedantic) dnf -yq update >/dev/null && dnf -yq install make gcc findutils diffutils perl python3 gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel >/dev/null ;; esac + +end_group "Install dependencies" @@ -1,16 +1,7 @@ # Library of functions shared by all CI scripts -if test true != "$GITHUB_ACTIONS" +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 @@ -23,27 +14,50 @@ else need_to_end_group= echo '::endgroup::' >&2 } - trap end_group EXIT +elif test true = "$GITLAB_CI" +then + begin_group () { + need_to_end_group=t + printf "\e[0Ksection_start:$(date +%s):$(echo "$1" | tr ' ' _)\r\e[0K$1\n" + trap "end_group '$1'" EXIT + set -x + } - group () { + end_group () { + test -n "$need_to_end_group" || return 0 set +x - begin_group "$1" - shift - # work around `dash` not supporting `set -o pipefail` - ( - "$@" 2>&1 - echo $? >exit.status - ) | - sed 's/^\(\([^ ]*\):\([0-9]*\):\([0-9]*:\) \)\(error\|warning\): /::\5 file=\2,line=\3::\1/' - res=$(cat exit.status) - rm exit.status - end_group - return $res + need_to_end_group= + printf "\e[0Ksection_end:$(date +%s):$(echo "$1" | tr ' ' _)\r\e[0K\n" + trap - EXIT } +else + begin_group () { :; } + end_group () { :; } - begin_group "CI setup" + set -x fi +group () { + group="$1" + shift + begin_group "$group" + + # work around `dash` not supporting `set -o pipefail` + ( + "$@" 2>&1 + echo $? >exit.status + ) | + sed 's/^\(\([^ ]*\):\([0-9]*\):\([0-9]*:\) \)\(error\|warning\): /::\5 file=\2,line=\3::\1/' + res=$(cat exit.status) + rm exit.status + + end_group "$group" + return $res +} + +begin_group "CI setup" +trap "end_group 'CI setup'" EXIT + # Set 'exit on error' for all CI scripts to let the caller know that # something went wrong. # @@ -71,10 +85,32 @@ skip_branch_tip_with_tag () { fi } +# Check whether we can use the path passed via the first argument as Git +# repository. +is_usable_git_repository () { + # We require Git in our PATH, otherwise we cannot access repositories + # at all. + if ! command -v git >/dev/null + then + return 1 + fi + + # And the target directory needs to be a proper Git repository. + if ! git -C "$1" rev-parse 2>/dev/null + then + return 1 + fi +} + # Save some info about the current commit's tree, so we can skip the build # job if we encounter the same tree again and can provide a useful info # message. save_good_tree () { + if ! is_usable_git_repository . + then + return + fi + echo "$(git rev-parse $CI_COMMIT^{tree}) $CI_COMMIT $CI_JOB_NUMBER $CI_JOB_ID" >>"$good_trees_file" # limit the file size tail -1000 "$good_trees_file" >"$good_trees_file".tmp @@ -90,6 +126,11 @@ skip_good_tree () { return fi + if ! is_usable_git_repository . + then + return + fi + if ! good_tree_info="$(grep "^$(git rev-parse $CI_COMMIT^{tree}) " "$good_trees_file")" then # Haven't seen this tree yet, or no cached good trees file yet. @@ -121,6 +162,11 @@ skip_good_tree () { } check_unignored_build_artifacts () { + if ! is_usable_git_repository . + then + return + fi + ! git ls-files --other --exclude-standard --error-unmatch \ -- ':/*' 2>/dev/null || { @@ -133,6 +179,26 @@ handle_failed_tests () { return 1 } +create_failed_test_artifacts () { + mkdir -p t/failed-test-artifacts + + 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 'print test failures' step below." + echo "See also the 'failed-tests-*' 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 +} + # GitHub Action doesn't set TERM, which is required by tput export TERM=${TERM:-dumb} @@ -156,11 +222,8 @@ then # among *all* phases) cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" - export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save" - export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml" - MAKEFLAGS="$MAKEFLAGS --jobs=10" - test windows_nt != "$CI_OS_NAME" || - GIT_TEST_OPTS="--no-chain-lint --no-bin-wrappers $GIT_TEST_OPTS" + GIT_TEST_OPTS="--write-junit-xml" + JOBS=10 elif test true = "$GITHUB_ACTIONS" then CI_TYPE=github-actions @@ -173,40 +236,70 @@ then 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 + create_failed_test_artifacts + return 1 + } + + cache_dir="$HOME/none" - 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 'print test failures' step below." - echo "See also the 'failed-tests-*' 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 + GIT_TEST_OPTS="--github-workflow-markup" + JOBS=10 +elif test true = "$GITLAB_CI" +then + CI_TYPE=gitlab-ci + CI_BRANCH="$CI_COMMIT_REF_NAME" + CI_COMMIT="$CI_COMMIT_SHA" + case "$CI_JOB_IMAGE" in + macos-*) + # GitLab CI has Python installed via multiple package managers, + # most notably via asdf and Homebrew. Ensure that our builds + # pick up the Homebrew one by prepending it to our PATH as the + # asdf one breaks tests. + export PATH="$(brew --prefix)/bin:$PATH" + + CI_OS_NAME=osx + ;; + alpine:*|fedora:*|ubuntu:*) + CI_OS_NAME=linux;; + *) + echo "Could not identify OS image" >&2 + env >&2 + exit 1 + ;; + esac + CI_REPO_SLUG="$CI_PROJECT_PATH" + CI_JOB_ID="$CI_JOB_ID" + CC="${CC_PACKAGE:-${CC:-gcc}}" + DONT_SKIP_TAGS=t + handle_failed_tests () { + create_failed_test_artifacts return 1 } cache_dir="$HOME/none" - export GIT_PROVE_OPTS="--timer --jobs 10" - 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" + runs_on_pool=$(echo "$CI_JOB_IMAGE" | tr : -) + JOBS=$(nproc) else echo "Could not identify CI type" >&2 env >&2 exit 1 fi +MAKEFLAGS="$MAKEFLAGS --jobs=$JOBS" +GIT_PROVE_OPTS="--timer --jobs $JOBS" + +GIT_TEST_OPTS="$GIT_TEST_OPTS --verbose-log -x" +case "$CI_OS_NAME" in +windows|windows_nt) + GIT_TEST_OPTS="$GIT_TEST_OPTS --no-chain-lint --no-bin-wrappers" + ;; +esac + +export GIT_TEST_OPTS +export GIT_PROVE_OPTS + good_trees_file="$cache_dir/good-trees" mkdir -p "$cache_dir" @@ -258,6 +351,9 @@ macos-*) then MAKEFLAGS="$MAKEFLAGS APPLE_COMMON_CRYPTO_SHA1=Yes" fi + + P4_PATH="$HOME/custom/p4" + export PATH="$P4_PATH:$PATH" ;; esac @@ -271,7 +367,7 @@ linux-musl) MAKEFLAGS="$MAKEFLAGS NO_REGEX=Yes ICONV_OMITS_BOM=Yes" MAKEFLAGS="$MAKEFLAGS GIT_TEST_UTF8_LOCALE=C.UTF-8" ;; -linux-leaks) +linux-leaks|linux-reftable-leaks) export SANITIZE=leak export GIT_TEST_PASSING_SANITIZE_LEAK=true export GIT_TEST_SANITIZE_LEAK_LOG=true @@ -285,5 +381,5 @@ esac MAKEFLAGS="$MAKEFLAGS CC=${CC:-cc}" -end_group +end_group "CI setup" set -x diff --git a/ci/print-test-failures.sh b/ci/print-test-failures.sh index 57277eefcd..b1f80aeac3 100755 --- a/ci/print-test-failures.sh +++ b/ci/print-test-failures.sh @@ -8,7 +8,7 @@ # Tracing executed commands would produce too much noise in the loop below. set +x -cd t/ +cd "${TEST_OUTPUT_DIRECTORY:-t/}" if ! ls test-results/*.exit >/dev/null 2>/dev/null then @@ -51,6 +51,12 @@ do tar czf failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir" continue ;; + gitlab-ci) + mkdir -p failed-test-artifacts + cp "${TEST_EXIT%.exit}.out" failed-test-artifacts/ + tar czf failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir" + continue + ;; *) echo "Unhandled CI type: $CI_TYPE" >&2 exit 1 diff --git a/ci/run-build-and-minimal-fuzzers.sh b/ci/run-build-and-minimal-fuzzers.sh new file mode 100755 index 0000000000..8ba486f659 --- /dev/null +++ b/ci/run-build-and-minimal-fuzzers.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# Build and test Git's fuzzers +# + +. ${0%/*}/lib.sh + +group "Build fuzzers" make \ + CC=clang \ + CXX=clang++ \ + CFLAGS="-fsanitize=fuzzer-no-link,address" \ + LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \ + fuzz-all + +for fuzzer in commit-graph date pack-headers pack-idx ; do + begin_group "fuzz-$fuzzer" + ./oss-fuzz/fuzz-$fuzzer -verbosity=0 -runs=1 || exit 1 + end_group "fuzz-$fuzzer" +done diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh index 2528f25e31..c192bd613c 100755 --- a/ci/run-build-and-tests.sh +++ b/ci/run-build-and-tests.sh @@ -37,6 +37,9 @@ linux-clang) linux-sha256) export GIT_TEST_DEFAULT_HASH=sha256 ;; +linux-reftable|linux-reftable-leaks|osx-reftable) + export GIT_TEST_DEFAULT_REF_FORMAT=reftable + ;; pedantic) # Don't run the tests; we only care about whether Git can be # built. @@ -50,6 +53,8 @@ if test -n "$run_tests" then group "Run tests" make test || handle_failed_tests + group "Run unit tests" \ + make DEFAULT_UNIT_TEST_TARGET=unit-tests-prove unit-tests fi check_unignored_build_artifacts diff --git a/ci/run-test-slice.sh b/ci/run-test-slice.sh index a3c67956a8..ae8094382f 100755 --- a/ci/run-test-slice.sh +++ b/ci/run-test-slice.sh @@ -15,4 +15,9 @@ group "Run tests" make --quiet -C t T="$(cd t && tr '\n' ' ')" || handle_failed_tests +# We only have one unit test at the moment, so run it in the first slice +if [ "$1" == "0" ] ; then + group "Run unit tests" make --quiet -C t unit-tests-prove +fi + check_unignored_build_artifacts @@ -182,6 +182,8 @@ void print_columns(const struct string_list *list, unsigned int colopts, { struct column_options nopts; + if (opts && (0 > opts->padding)) + BUG("padding must be non-negative"); if (!list->nr) return; assert((colopts & COL_ENABLE_MASK) != COL_AUTO); @@ -361,6 +363,8 @@ int run_column_filter(int colopts, const struct column_options *opts) { struct strvec *argv; + if (opts && (0 > opts->padding)) + BUG("padding must be non-negative"); if (fd_out != -1) return -1; diff --git a/combine-diff.c b/combine-diff.c index f90f442482..d6d6fa1689 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -2,7 +2,6 @@ #include "object-store-ll.h" #include "commit.h" #include "convert.h" -#include "blob.h" #include "diff.h" #include "diffcore.h" #include "environment.h" @@ -338,6 +337,8 @@ static char *grab_blob(struct repository *r, free_filespec(df); } else { blob = repo_read_object_file(r, oid, &type, size); + if (!blob) + die(_("unable to read %s"), oid_to_hex(oid)); if (type != OBJ_BLOB) die("object '%s' is not a blob!", oid_to_hex(oid)); } diff --git a/command-list.txt b/command-list.txt index 54b2a50f5f..c4cd0f352b 100644 --- a/command-list.txt +++ b/command-list.txt @@ -160,6 +160,7 @@ git-reflog ancillarymanipulators complete git-remote ancillarymanipulators complete git-repack ancillarymanipulators complete git-replace ancillarymanipulators complete +git-replay plumbingmanipulators git-request-pull foreignscminterface complete git-rerere ancillaryinterrogators git-reset mainporcelain history diff --git a/commit-graph.c b/commit-graph.c index ee66098e07..45417d7412 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1,14 +1,13 @@ #include "git-compat-util.h" #include "config.h" +#include "csum-file.h" #include "gettext.h" #include "hex.h" #include "lockfile.h" -#include "pack.h" #include "packfile.h" #include "commit.h" #include "object.h" #include "refs.h" -#include "revision.h" #include "hash-lookup.h" #include "commit-graph.h" #include "object-file.h" @@ -275,68 +274,37 @@ struct commit_graph *load_commit_graph_one_fd_st(struct repository *r, return ret; } -static int verify_commit_graph_lite(struct commit_graph *g) +static int graph_read_oid_fanout(const unsigned char *chunk_start, + size_t chunk_size, void *data) { + struct commit_graph *g = data; int i; - /* - * Basic validation shared between parse_commit_graph() - * which'll be called every time the graph is used, and the - * much more expensive verify_commit_graph() used by - * "commit-graph verify". - * - * There should only be very basic checks here to ensure that - * we don't e.g. segfault in fill_commit_in_graph(), but - * because this is a very hot codepath nothing that e.g. loops - * over g->num_commits, or runs a checksum on the commit-graph - * itself. - */ - if (!g->chunk_oid_fanout) { - error("commit-graph is missing the OID Fanout chunk"); - return 1; - } - if (!g->chunk_oid_lookup) { - error("commit-graph is missing the OID Lookup chunk"); - return 1; - } - if (!g->chunk_commit_data) { - error("commit-graph is missing the Commit Data chunk"); - return 1; - } + if (chunk_size != 256 * sizeof(uint32_t)) + return error(_("commit-graph oid fanout chunk is wrong size")); + g->chunk_oid_fanout = (const uint32_t *)chunk_start; + g->num_commits = ntohl(g->chunk_oid_fanout[255]); for (i = 0; i < 255; i++) { uint32_t oid_fanout1 = ntohl(g->chunk_oid_fanout[i]); uint32_t oid_fanout2 = ntohl(g->chunk_oid_fanout[i + 1]); if (oid_fanout1 > oid_fanout2) { - error("commit-graph fanout values out of order"); + error(_("commit-graph fanout values out of order")); return 1; } } - if (ntohl(g->chunk_oid_fanout[255]) != g->num_commits) { - error("commit-graph oid table and fanout disagree on size"); - return 1; - } return 0; } -static int graph_read_oid_fanout(const unsigned char *chunk_start, - size_t chunk_size, void *data) -{ - struct commit_graph *g = data; - if (chunk_size != 256 * sizeof(uint32_t)) - return error("commit-graph oid fanout chunk is wrong size"); - g->chunk_oid_fanout = (const uint32_t *)chunk_start; - return 0; -} - static int graph_read_oid_lookup(const unsigned char *chunk_start, size_t chunk_size, void *data) { struct commit_graph *g = data; g->chunk_oid_lookup = chunk_start; - g->num_commits = chunk_size / g->hash_len; + if (chunk_size / g->hash_len != g->num_commits) + return error(_("commit-graph OID lookup chunk is the wrong size")); return 0; } @@ -344,8 +312,8 @@ static int graph_read_commit_data(const unsigned char *chunk_start, size_t chunk_size, void *data) { struct commit_graph *g = data; - if (chunk_size != g->num_commits * GRAPH_DATA_WIDTH) - return error("commit-graph commit data chunk is wrong size"); + if (chunk_size / GRAPH_DATA_WIDTH != g->num_commits) + return error(_("commit-graph commit data chunk is wrong size")); g->chunk_commit_data = chunk_start; return 0; } @@ -354,8 +322,8 @@ static int graph_read_generation_data(const unsigned char *chunk_start, size_t chunk_size, void *data) { struct commit_graph *g = data; - if (chunk_size != g->num_commits * sizeof(uint32_t)) - return error("commit-graph generations chunk is wrong size"); + if (chunk_size / sizeof(uint32_t) != g->num_commits) + return error(_("commit-graph generations chunk is wrong size")); g->chunk_generation_data = chunk_start; return 0; } @@ -364,8 +332,8 @@ static int graph_read_bloom_index(const unsigned char *chunk_start, size_t chunk_size, void *data) { struct commit_graph *g = data; - if (chunk_size != g->num_commits * 4) { - warning("commit-graph changed-path index chunk is too small"); + if (chunk_size / 4 != g->num_commits) { + warning(_("commit-graph changed-path index chunk is too small")); return -1; } g->chunk_bloom_indexes = chunk_start; @@ -379,8 +347,8 @@ static int graph_read_bloom_data(const unsigned char *chunk_start, uint32_t hash_version; if (chunk_size < BLOOMDATA_CHUNK_HEADER_SIZE) { - warning("ignoring too-small changed-path chunk" - " (%"PRIuMAX" < %"PRIuMAX") in commit-graph file", + warning(_("ignoring too-small changed-path chunk" + " (%"PRIuMAX" < %"PRIuMAX") in commit-graph file"), (uintmax_t)chunk_size, (uintmax_t)BLOOMDATA_CHUNK_HEADER_SIZE); return -1; @@ -462,9 +430,19 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s, GRAPH_HEADER_SIZE, graph->num_chunks, 1)) goto free_and_return; - read_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, graph_read_oid_fanout, graph); - read_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, graph_read_oid_lookup, graph); - read_chunk(cf, GRAPH_CHUNKID_DATA, graph_read_commit_data, graph); + if (read_chunk(cf, GRAPH_CHUNKID_OIDFANOUT, graph_read_oid_fanout, graph)) { + error(_("commit-graph required OID fanout chunk missing or corrupted")); + goto free_and_return; + } + if (read_chunk(cf, GRAPH_CHUNKID_OIDLOOKUP, graph_read_oid_lookup, graph)) { + error(_("commit-graph required OID lookup chunk missing or corrupted")); + goto free_and_return; + } + if (read_chunk(cf, GRAPH_CHUNKID_DATA, graph_read_commit_data, graph)) { + error(_("commit-graph required commit data chunk missing or corrupted")); + goto free_and_return; + } + pair_chunk(cf, GRAPH_CHUNKID_EXTRAEDGES, &graph->chunk_extra_edges, &graph->chunk_extra_edges_size); pair_chunk(cf, GRAPH_CHUNKID_BASE, &graph->chunk_base_graphs, @@ -499,9 +477,6 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s, oidread(&graph->oid, graph->data + graph->data_len - graph->hash_len); - if (verify_commit_graph_lite(graph)) - goto free_and_return; - free_chunkfile(cf); return graph; @@ -629,7 +604,7 @@ int open_commit_graph_chain(const char *chain_file, /* treat empty files the same as missing */ errno = ENOENT; } else { - warning("commit-graph chain file too small"); + warning(_("commit-graph chain file too small")); errno = EINVAL; } return 0; @@ -831,6 +806,9 @@ struct bloom_filter_settings *get_bloom_filter_settings(struct repository *r) void close_commit_graph(struct raw_object_store *o) { + if (!o->commit_graph) + return; + clear_commit_graph_data_slab(&commit_graph_data_slab); free_commit_graph(o->commit_graph); o->commit_graph = NULL; @@ -970,7 +948,7 @@ static int fill_commit_in_graph(struct repository *r, parent_data_pos = edge_value & GRAPH_EDGE_LAST_MASK; do { if (g->chunk_extra_edges_size / sizeof(uint32_t) <= parent_data_pos) { - error("commit-graph extra-edges pointer out of bounds"); + error(_("commit-graph extra-edges pointer out of bounds")); free_commit_list(item->parents); item->parents = NULL; item->object.parsed = 0; @@ -1029,7 +1007,7 @@ struct commit *lookup_commit_in_graph(struct repository *repo, const struct obje uint32_t pos; if (commit_graph_paranoia == -1) - commit_graph_paranoia = git_env_bool(GIT_COMMIT_GRAPH_PARANOIA, 1); + commit_graph_paranoia = git_env_bool(GIT_COMMIT_GRAPH_PARANOIA, 0); if (!prepare_commit_graph(repo)) return NULL; @@ -2641,19 +2619,16 @@ cleanup: oid_array_clear(&ctx->oids); clear_topo_level_slab(&topo_levels); - if (ctx->commit_graph_filenames_after) { - for (i = 0; i < ctx->num_commit_graphs_after; i++) { - free(ctx->commit_graph_filenames_after[i]); - free(ctx->commit_graph_hash_after[i]); - } - - for (i = 0; i < ctx->num_commit_graphs_before; i++) - free(ctx->commit_graph_filenames_before[i]); + for (i = 0; i < ctx->num_commit_graphs_before; i++) + free(ctx->commit_graph_filenames_before[i]); + free(ctx->commit_graph_filenames_before); - free(ctx->commit_graph_filenames_after); - free(ctx->commit_graph_filenames_before); - free(ctx->commit_graph_hash_after); + for (i = 0; i < ctx->num_commit_graphs_after; i++) { + free(ctx->commit_graph_filenames_after[i]); + free(ctx->commit_graph_hash_after[i]); } + free(ctx->commit_graph_filenames_after); + free(ctx->commit_graph_hash_after); free(ctx); @@ -2690,10 +2665,6 @@ static int verify_one_commit_graph(struct repository *r, struct commit *seen_gen_zero = NULL; struct commit *seen_gen_non_zero = NULL; - verify_commit_graph_error = verify_commit_graph_lite(g); - if (verify_commit_graph_error) - return verify_commit_graph_error; - if (!commit_graph_checksum_valid(g)) { graph_report(_("the commit-graph file has incorrect checksum and is likely corrupt")); verify_commit_graph_error = VERIFY_COMMIT_GRAPH_ERROR_HASH; diff --git a/commit-reach.c b/commit-reach.c index a868a575ea..ecc913fc99 100644 --- a/commit-reach.c +++ b/commit-reach.c @@ -4,7 +4,6 @@ #include "decorate.h" #include "hex.h" #include "prio-queue.h" -#include "tree.h" #include "ref-filter.h" #include "revision.h" #include "tag.h" @@ -8,7 +8,6 @@ #include "repository.h" #include "object-name.h" #include "object-store-ll.h" -#include "pkt-line.h" #include "utf8.h" #include "diff.h" #include "revision.h" @@ -23,7 +22,6 @@ #include "advice.h" #include "refs.h" #include "commit-reach.h" -#include "run-command.h" #include "setup.h" #include "shallow.h" #include "tree.h" @@ -577,7 +575,7 @@ int repo_parse_commit_internal(struct repository *r, static int commit_graph_paranoia = -1; if (commit_graph_paranoia == -1) - commit_graph_paranoia = git_env_bool(GIT_COMMIT_GRAPH_PARANOIA, 1); + commit_graph_paranoia = git_env_bool(GIT_COMMIT_GRAPH_PARANOIA, 0); if (commit_graph_paranoia && !has_object(r, &item->object.oid, 0)) { unparse_commit(r, &item->object.oid); @@ -1783,7 +1781,7 @@ const char *find_commit_header(const char *msg, const char *key, size_t *out_len * Returns the number of bytes from the tail to ignore, to be fed as * the second parameter to append_signoff(). */ -size_t ignore_non_trailer(const char *buf, size_t len) +size_t ignored_log_message_bytes(const char *buf, size_t len) { size_t boc = 0; size_t bol = 0; @@ -294,8 +294,8 @@ const char *find_header_mem(const char *msg, size_t len, const char *find_commit_header(const char *msg, const char *key, size_t *out_len); -/* Find the end of the log message, the right place for a new trailer. */ -size_t ignore_non_trailer(const char *buf, size_t len); +/* Find the number of bytes to ignore from the end of a log message. */ +size_t ignored_log_message_bytes(const char *buf, size_t len); typedef int (*each_mergetag_fn)(struct commit *commit, struct commit_extra_header *extra, void *cb_data); diff --git a/compat/compiler.h b/compat/compiler.h index 10dbb65937..e9ad9db84f 100644 --- a/compat/compiler.h +++ b/compat/compiler.h @@ -1,7 +1,6 @@ #ifndef COMPILER_H #define COMPILER_H -#include "git-compat-util.h" #include "strbuf.h" #ifdef __GLIBC__ diff --git a/compat/disk.h b/compat/disk.h index 6c979c27d8..23bc1bef86 100644 --- a/compat/disk.h +++ b/compat/disk.h @@ -1,7 +1,6 @@ #ifndef COMPAT_DISK_H #define COMPAT_DISK_H -#include "git-compat-util.h" #include "abspath.h" #include "gettext.h" diff --git a/compat/fsmonitor/fsm-health-win32.c b/compat/fsmonitor/fsm-health-win32.c index 2d4e245beb..2aa8c219ac 100644 --- a/compat/fsmonitor/fsm-health-win32.c +++ b/compat/fsmonitor/fsm-health-win32.c @@ -4,6 +4,7 @@ #include "fsm-health.h" #include "fsmonitor--daemon.h" #include "gettext.h" +#include "simple-ipc.h" /* * Every minute wake up and test our health. diff --git a/compat/fsmonitor/fsm-listen-darwin.c b/compat/fsmonitor/fsm-listen-darwin.c index 11b56d3ef1..2fc67442eb 100644 --- a/compat/fsmonitor/fsm-listen-darwin.c +++ b/compat/fsmonitor/fsm-listen-darwin.c @@ -29,6 +29,7 @@ #include "fsmonitor--daemon.h" #include "fsmonitor-path-utils.h" #include "gettext.h" +#include "simple-ipc.h" #include "string-list.h" #include "trace.h" diff --git a/compat/fsmonitor/fsm-listen-win32.c b/compat/fsmonitor/fsm-listen-win32.c index 90a2412284..5a21dade7b 100644 --- a/compat/fsmonitor/fsm-listen-win32.c +++ b/compat/fsmonitor/fsm-listen-win32.c @@ -4,6 +4,7 @@ #include "fsm-listen.h" #include "fsmonitor--daemon.h" #include "gettext.h" +#include "simple-ipc.h" #include "trace2.h" /* diff --git a/compat/mingw.c b/compat/mingw.c index ec5280da16..320fb99a90 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -255,6 +255,8 @@ int mingw_core_config(const char *var, const char *value, } if (!strcmp(var, "core.unsetenvvars")) { + if (!value) + return config_error_nonbool(var); free(unset_environment_variables); unset_environment_variables = xstrdup(value); return 0; @@ -705,13 +707,24 @@ ssize_t mingw_write(int fd, const void *buf, size_t len) { ssize_t result = write(fd, buf, len); - if (result < 0 && errno == EINVAL && buf) { + if (result < 0 && (errno == EINVAL || errno == ENOSPC) && buf) { + int orig = errno; + /* check if fd is a pipe */ HANDLE h = (HANDLE) _get_osfhandle(fd); - if (GetFileType(h) == FILE_TYPE_PIPE) + if (GetFileType(h) != FILE_TYPE_PIPE) + errno = orig; + else if (orig == EINVAL) errno = EPIPE; - else - errno = EINVAL; + else { + DWORD buf_size; + + if (!GetNamedPipeInfo(h, NULL, NULL, &buf_size, NULL)) + buf_size = 4096; + if (len > buf_size) + return write(fd, buf, buf_size); + errno = orig; + } } return result; @@ -2682,6 +2695,30 @@ static PSID get_current_user_sid(void) return result; } +static BOOL user_sid_to_user_name(PSID sid, LPSTR *str) +{ + SID_NAME_USE pe_use; + DWORD len_user = 0, len_domain = 0; + BOOL translate_sid_to_user; + + /* + * returns only FALSE, because the string pointers are NULL + */ + LookupAccountSidA(NULL, sid, NULL, &len_user, NULL, &len_domain, + &pe_use); + /* + * Alloc needed space of the strings + */ + ALLOC_ARRAY((*str), (size_t)len_domain + (size_t)len_user); + translate_sid_to_user = LookupAccountSidA(NULL, sid, + (*str) + len_domain, &len_user, *str, &len_domain, &pe_use); + if (!translate_sid_to_user) + FREE_AND_NULL(*str); + else + (*str)[len_domain] = '/'; + return translate_sid_to_user; +} + static int acls_supported(const char *path) { size_t offset = offset_1st_component(path); @@ -2763,27 +2800,47 @@ int is_path_owned_by_current_sid(const char *path, struct strbuf *report) strbuf_addf(report, "'%s' is on a file system that does " "not record ownership\n", path); } else if (report) { - LPSTR str1, str2, to_free1 = NULL, to_free2 = NULL; + LPSTR str1, str2, str3, str4, to_free1 = NULL, + to_free3 = NULL, to_local_free2 = NULL, + to_local_free4 = NULL; - if (ConvertSidToStringSidA(sid, &str1)) + if (user_sid_to_user_name(sid, &str1)) to_free1 = str1; else str1 = "(inconvertible)"; - - if (!current_user_sid) - str2 = "(none)"; - else if (!IsValidSid(current_user_sid)) - str2 = "(invalid)"; - else if (ConvertSidToStringSidA(current_user_sid, &str2)) - to_free2 = str2; + if (ConvertSidToStringSidA(sid, &str2)) + to_local_free2 = str2; else str2 = "(inconvertible)"; + + if (!current_user_sid) { + str3 = "(none)"; + str4 = "(none)"; + } + else if (!IsValidSid(current_user_sid)) { + str3 = "(invalid)"; + str4 = "(invalid)"; + } else { + if (user_sid_to_user_name(current_user_sid, + &str3)) + to_free3 = str3; + else + str3 = "(inconvertible)"; + if (ConvertSidToStringSidA(current_user_sid, + &str4)) + to_local_free4 = str4; + else + str4 = "(inconvertible)"; + } strbuf_addf(report, "'%s' is owned by:\n" - "\t'%s'\nbut the current user is:\n" - "\t'%s'\n", path, str1, str2); - LocalFree(to_free1); - LocalFree(to_free2); + "\t%s (%s)\nbut the current user is:\n" + "\t%s (%s)\n", + path, str1, str2, str3, str4); + free(to_free1); + LocalFree(to_local_free2); + free(to_free3); + LocalFree(to_local_free4); } } diff --git a/compat/simple-ipc/ipc-shared.c b/compat/simple-ipc/ipc-shared.c index e5e1dda8cc..cb176d966f 100644 --- a/compat/simple-ipc/ipc-shared.c +++ b/compat/simple-ipc/ipc-shared.c @@ -1,8 +1,5 @@ #include "git-compat-util.h" #include "simple-ipc.h" -#include "strbuf.h" -#include "pkt-line.h" -#include "thread-utils.h" #ifndef SUPPORTS_SIMPLE_IPC /* diff --git a/compat/simple-ipc/ipc-unix-socket.c b/compat/simple-ipc/ipc-unix-socket.c index b2f4f22ce4..9b3f2cdf8c 100644 --- a/compat/simple-ipc/ipc-unix-socket.c +++ b/compat/simple-ipc/ipc-unix-socket.c @@ -2,7 +2,6 @@ #include "gettext.h" #include "simple-ipc.h" #include "strbuf.h" -#include "pkt-line.h" #include "thread-utils.h" #include "trace2.h" #include "unix-socket.h" @@ -30,15 +30,12 @@ #include "pager.h" #include "path.h" #include "utf8.h" -#include "dir.h" #include "color.h" -#include "replace-object.h" #include "refs.h" #include "setup.h" #include "strvec.h" #include "trace2.h" #include "wildmatch.h" -#include "worktree.h" #include "ws.h" #include "write-or-die.h" @@ -98,7 +95,6 @@ static long config_file_ftell(struct config_source *conf) return ftell(conf->u.file); } - static int config_buf_fgetc(struct config_source *conf) { if (conf->u.buf.pos < conf->u.buf.len) @@ -1386,10 +1382,15 @@ static int git_default_core_config(const char *var, const char *value, return 0; } if (!strcmp(var, "core.checkstat")) { + if (!value) + return config_error_nonbool(var); if (!strcasecmp(value, "default")) check_stat = 1; else if (!strcasecmp(value, "minimal")) check_stat = 0; + else + return error(_("invalid value for '%s': '%s'"), + var, value); } if (!strcmp(var, "core.quotepath")) { @@ -1546,12 +1547,12 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.checkroundtripencoding")) { - check_roundtrip_encoding = xstrdup(value); - return 0; - } + if (!strcmp(var, "core.checkroundtripencoding")) + return git_config_string(&check_roundtrip_encoding, var, value); if (!strcmp(var, "core.notesref")) { + if (!value) + return config_error_nonbool(var); notes_ref_name = xstrdup(value); return 0; } @@ -1619,6 +1620,8 @@ static int git_default_core_config(const char *var, const char *value, } if (!strcmp(var, "core.createobject")) { + if (!value) + return config_error_nonbool(var); if (!strcmp(value, "rename")) object_creation_mode = OBJECT_CREATION_USES_RENAMES; else if (!strcmp(value, "link")) @@ -1984,7 +1987,27 @@ char *git_system_config(void) return system_config; } -void git_global_config(char **user_out, char **xdg_out) +char *git_global_config(void) +{ + char *user_config, *xdg_config; + + git_global_config_paths(&user_config, &xdg_config); + if (!user_config) { + free(xdg_config); + return NULL; + } + + if (access_or_warn(user_config, R_OK, 0) && xdg_config && + !access_or_warn(xdg_config, R_OK, 0)) { + free(user_config); + return xdg_config; + } else { + free(xdg_config); + return user_config; + } +} + +void git_global_config_paths(char **user_out, char **xdg_out) { char *user_config = xstrdup_or_null(getenv("GIT_CONFIG_GLOBAL")); char *xdg_config = NULL; @@ -2037,7 +2060,7 @@ static int do_git_config_sequence(const struct config_options *opts, data, CONFIG_SCOPE_SYSTEM, NULL); - git_global_config(&user_config, &xdg_config); + git_global_config_paths(&user_config, &xdg_config); if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK)) ret += git_config_from_file_with_options(fn, xdg_config, data, @@ -3414,7 +3437,6 @@ out_free: write_err_out: ret = write_error(get_lock_file_path(&lock)); goto out_free; - } void git_config_set_multivar_in_file(const char *config_filename, @@ -382,7 +382,8 @@ int config_error_nonbool(const char *); #endif char *git_system_config(void); -void git_global_config(char **user, char **xdg); +char *git_global_config(void); +void git_global_config_paths(char **user, char **xdg); int git_config_parse_parameter(const char *, config_fn_t fn, void *data); diff --git a/config.mak.uname b/config.mak.uname index 3bb03f423a..dacc95172d 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -158,6 +158,19 @@ ifeq ($(uname_S),Darwin) ifeq ($(shell test -x /usr/local/opt/gettext/bin/msgfmt && echo y),y) MSGFMT = /usr/local/opt/gettext/bin/msgfmt endif + # On newer ARM-based machines the default installation path has changed to + # /opt/homebrew. Include it in our search paths so that the user does not + # have to configure this manually. + # + # Note that we do not employ the same workaround as above where we manually + # add gettext. The issue was fixed more than three years ago by now, and at + # that point there haven't been any ARM-based Macs yet. + else ifeq ($(shell test -d /opt/homebrew/ && echo y),y) + BASIC_CFLAGS += -I/opt/homebrew/include + BASIC_LDFLAGS += -L/opt/homebrew/lib + ifeq ($(shell test -x /opt/homebrew/bin/msgfmt && echo y),y) + MSGFMT = /opt/homebrew/bin/msgfmt + endif endif # The builtin FSMonitor on MacOS builds upon Simple-IPC. Both require diff --git a/configure.ac b/configure.ac index 276593cd9d..d1a96da14e 100644 --- a/configure.ac +++ b/configure.ac @@ -94,7 +94,7 @@ AC_DEFUN([GIT_PARSE_WITH_SET_MAKE_VAR], [AC_ARG_WITH([$1], [AS_HELP_STRING([--with-$1=VALUE], $3)], if test -n "$withval"; then - if test "$withval" = "yes" -o "$withval" = "no"; then + if test "$withval" = "yes" || test "$withval" = "no"; then AC_MSG_WARN([You likely do not want either 'yes' or 'no' as] [a value for $1 ($2). Maybe you do...?]) fi diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 6b819e2fbd..804629c525 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -974,6 +974,35 @@ target_link_libraries(test-fake-ssh common-main) parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS") list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") +#unit-tests +add_library(unit-test-lib OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/test-lib.c) + +parse_makefile_for_scripts(unit_test_PROGRAMS "UNIT_TEST_PROGRAMS" "") +foreach(unit_test ${unit_test_PROGRAMS}) + add_executable("${unit_test}" "${CMAKE_SOURCE_DIR}/t/unit-tests/${unit_test}.c") + target_link_libraries("${unit_test}" unit-test-lib common-main) + set_target_properties("${unit_test}" + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin) + if(MSVC) + set_target_properties("${unit_test}" + PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/t/unit-tests/bin) + set_target_properties("${unit_test}" + PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/t/unit-tests/bin) + endif() + list(APPEND PROGRAMS_BUILT "${unit_test}") + + # t-basic intentionally fails tests, to validate the unit-test infrastructure. + # Therefore, it should only be run as part of t0080, which verifies that it + # fails only in the expected ways. + # + # All other unit tests should be run. + if(NOT ${unit_test} STREQUAL "t-basic") + add_test(NAME "t.unit-tests.${unit_test}" + COMMAND "./${unit_test}" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/t/unit-tests/bin) + endif() +endforeach() + #test-tool parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS") @@ -1093,17 +1122,18 @@ if(NOT ${CMAKE_BINARY_DIR}/CMakeCache.txt STREQUAL ${CACHE_PATH}) file(COPY ${CMAKE_SOURCE_DIR}/contrib/completion/git-completion.bash DESTINATION ${CMAKE_BINARY_DIR}/contrib/completion/) endif() -file(GLOB test_scipts "${CMAKE_SOURCE_DIR}/t/t[0-9]*.sh") +file(GLOB test_scripts "${CMAKE_SOURCE_DIR}/t/t[0-9]*.sh") #test -foreach(tsh ${test_scipts}) - add_test(NAME ${tsh} +foreach(tsh ${test_scripts}) + string(REGEX REPLACE ".*/(.*)\\.sh" "\\1" test_name ${tsh}) + add_test(NAME "t.suite.${test_name}" COMMAND ${SH_EXE} ${tsh} --no-bin-wrappers --no-chain-lint -vx WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/t) endforeach() # This test script takes an extremely long time and is known to time out even # on fast machines because it requires in excess of one hour to run -set_tests_properties("${CMAKE_SOURCE_DIR}/t/t7112-reset-submodule.sh" PROPERTIES TIMEOUT 4000) +set_tests_properties("t.suite.t7112-reset-submodule" PROPERTIES TIMEOUT 4000) endif()#BUILD_TESTING diff --git a/contrib/coccinelle/xstrncmpz.cocci b/contrib/coccinelle/xstrncmpz.cocci new file mode 100644 index 0000000000..ccb39e2bc0 --- /dev/null +++ b/contrib/coccinelle/xstrncmpz.cocci @@ -0,0 +1,28 @@ +@@ +expression S, T, L; +@@ +( +- strncmp(S, T, L) || S[L] ++ !!xstrncmpz(S, T, L) +| +- strncmp(S, T, L) || S[L] != '\0' ++ !!xstrncmpz(S, T, L) +| +- strncmp(S, T, L) || T[L] ++ !!xstrncmpz(T, S, L) +| +- strncmp(S, T, L) || T[L] != '\0' ++ !!xstrncmpz(T, S, L) +| +- !strncmp(S, T, L) && !S[L] ++ !xstrncmpz(S, T, L) +| +- !strncmp(S, T, L) && S[L] == '\0' ++ !xstrncmpz(S, T, L) +| +- !strncmp(S, T, L) && !T[L] ++ !xstrncmpz(T, S, L) +| +- !strncmp(S, T, L) && T[L] == '\0' ++ !xstrncmpz(T, S, L) +) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 13a39ebd2e..fcf1afd75d 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -122,6 +122,40 @@ __git () ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null } +# Helper function to read the first line of a file into a variable. +# __git_eread requires 2 arguments, the file path and the name of the +# variable, in that order. +# +# This is taken from git-prompt.sh. +__git_eread () +{ + test -r "$1" && IFS=$'\r\n' read -r "$2" <"$1" +} + +# Runs git in $__git_repo_path to determine whether a pseudoref exists. +# 1: The pseudo-ref to search +__git_pseudoref_exists () +{ + local ref=$1 + local head + + __git_find_repo_path + + # If the reftable is in use, we have to shell out to 'git rev-parse' + # to determine whether the ref exists instead of looking directly in + # the filesystem to determine whether the ref exists. Otherwise, use + # Bash builtins since executing Git commands are expensive on some + # platforms. + if __git_eread "$__git_repo_path/HEAD" head; then + if [ "$head" == "ref: refs/heads/.invalid" ]; then + __git show-ref --exists "$ref" + return $? + fi + fi + + [ -f "$__git_repo_path/$ref" ] +} + # Removes backslash escaping, single quotes and double quotes from a word, # stores the result in the variable $dequoted_word. # 1: The word to dequote. @@ -1449,12 +1483,32 @@ _git_bisect () { __git_has_doubledash && return - local subcommands="start bad good skip reset visualize replay log run" - local subcommand="$(__git_find_on_cmdline "$subcommands")" + __git_find_repo_path + + # If a bisection is in progress get the terms being used. + local term_bad term_good + if [ -f "$__git_repo_path"/BISECT_TERMS ]; then + term_bad=$(__git bisect terms --term-bad) + term_good=$(__git bisect terms --term-good) + fi + + # We will complete any custom terms, but still always complete the + # more usual bad/new/good/old because git bisect gives a good error + # message if these are given when not in use, and that's better than + # silent refusal to complete if the user is confused. + # + # We want to recognize 'view' but not complete it, because it overlaps + # with 'visualize' too much and is just an alias for it. + # + local completable_subcommands="start bad new $term_bad good old $term_good terms skip reset visualize replay log run help" + local all_subcommands="$completable_subcommands view" + + local subcommand="$(__git_find_on_cmdline "$all_subcommands")" + if [ -z "$subcommand" ]; then __git_find_repo_path if [ -f "$__git_repo_path"/BISECT_START ]; then - __gitcomp "$subcommands" + __gitcomp "$completable_subcommands" else __gitcomp "replay start" fi @@ -1462,7 +1516,26 @@ _git_bisect () fi case "$subcommand" in - bad|good|reset|skip|start) + start) + case "$cur" in + --*) + __gitcomp "--first-parent --no-checkout --term-new --term-bad --term-old --term-good" + return + ;; + *) + __git_complete_refs + ;; + esac + ;; + terms) + __gitcomp "--term-good --term-old --term-bad --term-new" + return + ;; + visualize|view) + __git_complete_log_opts + return + ;; + bad|new|"$term_bad"|good|old|"$term_good"|reset|skip) __git_complete_refs ;; *) @@ -1624,8 +1697,7 @@ __git_cherry_pick_inprogress_options=$__git_sequencer_inprogress_options _git_cherry_pick () { - __git_find_repo_path - if [ -f "$__git_repo_path"/CHERRY_PICK_HEAD ]; then + if __git_pseudoref_exists CHERRY_PICK_HEAD; then __gitcomp "$__git_cherry_pick_inprogress_options" return fi @@ -1775,7 +1847,7 @@ __git_diff_common_options="--stat --numstat --shortstat --summary --output= --output-indicator-context= --output-indicator-new= --output-indicator-old= --ws-error-highlight= - --pickaxe-all --pickaxe-regex + --pickaxe-all --pickaxe-regex --patch-with-raw " # Options for diff/difftool @@ -2039,6 +2111,16 @@ __git_log_common_options=" --min-age= --until= --before= --min-parents= --max-parents= --no-min-parents --no-max-parents + --alternate-refs --ancestry-path + --author-date-order --basic-regexp + --bisect --boundary --exclude-first-parent-only + --exclude-hidden --extended-regexp + --fixed-strings --grep-reflog + --ignore-missing --left-only --perl-regexp + --reflog --regexp-ignore-case --remove-empty + --right-only --show-linear-break + --show-notes-by-default --show-pulls + --since-as-filter --single-worktree " # Options that go well for log and gitk (not shortlog) __git_log_gitk_options=" @@ -2054,6 +2136,7 @@ __git_log_shortlog_options=" # Options accepted by log and show __git_log_show_options=" --diff-merges --diff-merges= --no-diff-merges --dd --remerge-diff + --encoding= " __git_diff_merges_opts="off none on first-parent 1 separate m combined c dense-combined cc remerge r" @@ -2061,13 +2144,15 @@ __git_diff_merges_opts="off none on first-parent 1 separate m combined c dense-c __git_log_pretty_formats="oneline short medium full fuller reference email raw format: tformat: mboxrd" __git_log_date_formats="relative iso8601 iso8601-strict rfc2822 short local default human raw unix auto: format:" -_git_log () +# Complete porcelain (i.e. not git-rev-list) options and at least some +# option arguments accepted by git-log. Note that this same set of options +# are also accepted by some other git commands besides git-log. +__git_complete_log_opts () { - __git_has_doubledash && return - __git_find_repo_path + COMPREPLY=() local merge="" - if [ -f "$__git_repo_path/MERGE_HEAD" ]; then + if __git_pseudoref_exists MERGE_HEAD; then merge="--merge" fi case "$prev,$cur" in @@ -2137,6 +2222,8 @@ _git_log () --no-walk --no-walk= --do-walk --parents --children --expand-tabs --expand-tabs= --no-expand-tabs + --clear-decorations --decorate-refs= + --decorate-refs-exclude= $merge $__git_diff_common_options " @@ -2158,6 +2245,16 @@ _git_log () return ;; esac +} + +_git_log () +{ + __git_has_doubledash && return + __git_find_repo_path + + __git_complete_log_opts + [ ${#COMPREPLY[@]} -eq 0 ] || return + __git_complete_revlist } @@ -2563,6 +2660,33 @@ __git_compute_config_vars () __git_config_vars="$(git help --config-for-completion)" } +__git_config_vars_all= +__git_compute_config_vars_all () +{ + test -n "$__git_config_vars_all" || + __git_config_vars_all="$(git --no-pager help --config)" +} + +__git_compute_first_level_config_vars_for_section () +{ + local section="$1" + __git_compute_config_vars + local this_section="__git_first_level_config_vars_for_section_${section}" + test -n "${!this_section}" || + printf -v "__git_first_level_config_vars_for_section_${section}" %s \ + "$(echo "$__git_config_vars" | awk -F. "/^${section}\.[a-z]/ { print \$2 }")" +} + +__git_compute_second_level_config_vars_for_section () +{ + local section="$1" + __git_compute_config_vars_all + local this_section="__git_second_level_config_vars_for_section_${section}" + test -n "${!this_section}" || + printf -v "__git_second_level_config_vars_for_section_${section}" %s \ + "$(echo "$__git_config_vars_all" | awk -F. "/^${section}\.</ { print \$3 }")" +} + __git_config_sections= __git_compute_config_sections () { @@ -2707,73 +2831,50 @@ __git_complete_config_variable_name () done case "$cur_" in - branch.*.*) + branch.*.*|guitool.*.*|difftool.*.*|man.*.*|mergetool.*.*|remote.*.*|submodule.*.*|url.*.*) local pfx="${cur_%.*}." cur_="${cur_##*.}" - __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_" "$sfx" + local section="${pfx%.*.}" + __git_compute_second_level_config_vars_for_section "${section}" + local this_section="__git_second_level_config_vars_for_section_${section}" + __gitcomp "${!this_section}" "$pfx" "$cur_" "$sfx" return ;; branch.*) local pfx="${cur_%.*}." cur_="${cur_#*.}" + local section="${pfx%.}" __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")" - __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_" "${sfx- }" - return - ;; - guitool.*.*) - local pfx="${cur_%.*}." - cur_="${cur_##*.}" - __gitcomp " - argPrompt cmd confirm needsFile noConsole noRescan - prompt revPrompt revUnmerged title - " "$pfx" "$cur_" "$sfx" - return - ;; - difftool.*.*) - local pfx="${cur_%.*}." - cur_="${cur_##*.}" - __gitcomp "cmd path" "$pfx" "$cur_" "$sfx" - return - ;; - man.*.*) - local pfx="${cur_%.*}." - cur_="${cur_##*.}" - __gitcomp "cmd path" "$pfx" "$cur_" "$sfx" - return - ;; - mergetool.*.*) - local pfx="${cur_%.*}." - cur_="${cur_##*.}" - __gitcomp "cmd path trustExitCode" "$pfx" "$cur_" "$sfx" + __git_compute_first_level_config_vars_for_section "${section}" + local this_section="__git_first_level_config_vars_for_section_${section}" + __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" return ;; pager.*) local pfx="${cur_%.*}." cur_="${cur_#*.}" __git_compute_all_commands - __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "${sfx- }" - return - ;; - remote.*.*) - local pfx="${cur_%.*}." - cur_="${cur_##*.}" - __gitcomp " - url proxy fetch push mirror skipDefaultUpdate - receivepack uploadpack tagOpt pushurl - " "$pfx" "$cur_" "$sfx" + __gitcomp_nl "$__git_all_commands" "$pfx" "$cur_" "${sfx:- }" return ;; remote.*) local pfx="${cur_%.*}." cur_="${cur_#*.}" + local section="${pfx%.}" __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "." - __gitcomp_nl_append "pushDefault" "$pfx" "$cur_" "${sfx- }" + __git_compute_first_level_config_vars_for_section "${section}" + local this_section="__git_first_level_config_vars_for_section_${section}" + __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" return ;; - url.*.*) + submodule.*) local pfx="${cur_%.*}." - cur_="${cur_##*.}" - __gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_" "$sfx" + cur_="${cur_#*.}" + local section="${pfx%.}" + __gitcomp_nl "$(__git config -f "$(__git rev-parse --show-toplevel)/.gitmodules" --get-regexp 'submodule.*.path' | awk -F. '{print $2}')" "$pfx" "$cur_" "." + __git_compute_first_level_config_vars_for_section "${section}" + local this_section="__git_first_level_config_vars_for_section_${section}" + __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" return ;; *.*) @@ -2952,7 +3053,7 @@ _git_restore () __gitcomp_builtin restore ;; *) - if __git rev-parse --verify --quiet HEAD >/dev/null; then + if __git_pseudoref_exists HEAD; then __git_complete_index_file "--modified" fi esac @@ -2962,8 +3063,7 @@ __git_revert_inprogress_options=$__git_sequencer_inprogress_options _git_revert () { - __git_find_repo_path - if [ -f "$__git_repo_path"/REVERT_HEAD ]; then + if __git_pseudoref_exists REVERT_HEAD; then __gitcomp "$__git_revert_inprogress_options" return fi @@ -3084,12 +3184,119 @@ __gitcomp_directories () COMPREPLY+=("$c/") _found=1 fi - done < <(git ls-tree -z -d --name-only HEAD $_tmp_dir) + done < <(__git ls-tree -z -d --name-only HEAD $_tmp_dir) if [[ $_found == 0 ]] && [[ "$cur" =~ /$ ]]; then # No possible further completions any deeper, so assume we're at # a leaf directory and just consider it complete __gitcomp_direct_append "$cur " + elif [[ $_found == 0 ]]; then + # No possible completions found. Avoid falling back to + # bash's default file and directory completion, because all + # valid completions have already been searched and the + # fallbacks can do nothing but mislead. In fact, they can + # mislead in three different ways: + # 1) Fallback file completion makes no sense when asking + # for directory completions, as this function does. + # 2) Fallback directory completion is bad because + # e.g. "/pro" is invalid and should NOT complete to + # "/proc". + # 3) Fallback file/directory completion only completes + # on paths that exist in the current working tree, + # i.e. which are *already* part of their + # sparse-checkout. Thus, normal file and directory + # completion is always useless for "git + # sparse-checkout add" and is also probelmatic for + # "git sparse-checkout set" unless using it to + # strictly narrow the checkout. + COMPREPLY=( "" ) + fi +} + +# In non-cone mode, the arguments to {set,add} are supposed to be +# patterns, relative to the toplevel directory. These can be any kind +# of general pattern, like 'subdir/*.c' and we can't complete on all +# of those. However, if the user presses Tab to get tab completion, we +# presume that they are trying to provide a pattern that names a specific +# path. +__gitcomp_slash_leading_paths () +{ + local dequoted_word pfx="" cur_ toplevel + + # Since we are dealing with a sparse-checkout, subdirectories may not + # exist in the local working copy. Therefore, we want to run all + # ls-files commands relative to the repository toplevel. + toplevel="$(git rev-parse --show-toplevel)/" + + __git_dequote "$cur" + + # If the paths provided by the user already start with '/', then + # they are considered relative to the toplevel of the repository + # already. If they do not start with /, then we need to adjust + # them to start with the appropriate prefix. + case "$cur" in + /*) + cur="${cur:1}" + ;; + *) + pfx="$(__git rev-parse --show-prefix)" + esac + + # Since sparse-index is limited to cone-mode, in non-cone-mode the + # list of valid paths is precisely the cached files in the index. + # + # NEEDSWORK: + # 1) We probably need to take care of cases where ls-files + # responds with special quoting. + # 2) We probably need to take care of cases where ${cur} has + # some kind of special quoting. + # 3) On top of any quoting from 1 & 2, we have to provide an extra + # level of quoting for any paths that contain a '*', '?', '\', + # '[', ']', or leading '#' or '!' since those will be + # interpreted by sparse-checkout as something other than a + # literal path character. + # Since there are two types of quoting here, this might get really + # complex. For now, just punt on all of this... + completions="$(__git -C "${toplevel}" -c core.quotePath=false \ + ls-files --cached -- "${pfx}${cur}*" \ + | sed -e s%^%/% -e 's%$% %')" + # Note, above, though that we needed all of the completions to be + # prefixed with a '/', and we want to add a space so that bash + # completion will actually complete an entry and let us move on to + # the next one. + + # Return what we've found. + if test -n "$completions"; then + # We found some completions; return them + local IFS=$'\n' + COMPREPLY=($completions) + else + # Do NOT fall back to bash-style all-local-files-and-dirs + # when we find no match. Such options are worse than + # useless: + # 1. "git sparse-checkout add" needs paths that are NOT + # currently in the working copy. "git + # sparse-checkout set" does as well, except in the + # special cases when users are only trying to narrow + # their sparse checkout to a subset of what they + # already have. + # + # 2. A path like '.config' is ambiguous as to whether + # the user wants all '.config' files throughout the + # tree, or just the one under the current directory. + # It would result in a warning from the + # sparse-checkout command due to this. As such, all + # completions of paths should be prefixed with a + # '/'. + # + # 3. We don't want paths prefixed with a '/' to + # complete files in the system root directory, we + # want it to complete on files relative to the + # repository root. + # + # As such, make sure that NO completions are offered rather + # than falling back to bash's default completions. + COMPREPLY=( "" ) fi } @@ -3097,6 +3304,7 @@ _git_sparse_checkout () { local subcommands="list init set disable add reapply" local subcommand="$(__git_find_on_cmdline "$subcommands")" + local using_cone=true if [ -z "$subcommand" ]; then __gitcomp "$subcommands" return @@ -3107,9 +3315,18 @@ _git_sparse_checkout () __gitcomp_builtin sparse-checkout_$subcommand "" "--" ;; set,*|add,*) - if [ "$(__git config core.sparseCheckoutCone)" == "true" ] || - [ -n "$(__git_find_on_cmdline --cone)" ]; then + if [[ "$(__git config core.sparseCheckout)" == "true" && + "$(__git config core.sparseCheckoutCone)" == "false" && + -z "$(__git_find_on_cmdline --cone)" ]]; then + using_cone=false + fi + if [[ -n "$(__git_find_on_cmdline --no-cone)" ]]; then + using_cone=false + fi + if [[ "$using_cone" == "true" ]]; then __gitcomp_directories + else + __gitcomp_slash_leading_paths fi esac } @@ -3592,7 +3809,7 @@ __gitk_main () __git_find_repo_path local merge="" - if [ -f "$__git_repo_path/MERGE_HEAD" ]; then + if __git_pseudoref_exists MERGE_HEAD; then merge="--merge" fi case "$cur" in diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 2c030050ae..71f179cba3 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -408,7 +408,7 @@ __git_ps1 () local repo_info rev_parse_exit_code repo_info="$(git rev-parse --git-dir --is-inside-git-dir \ - --is-bare-repository --is-inside-work-tree \ + --is-bare-repository --is-inside-work-tree --show-ref-format \ --short HEAD 2>/dev/null)" rev_parse_exit_code="$?" @@ -421,6 +421,8 @@ __git_ps1 () short_sha="${repo_info##*$'\n'}" repo_info="${repo_info%$'\n'*}" fi + local ref_format="${repo_info##*$'\n'}" + repo_info="${repo_info%$'\n'*}" local inside_worktree="${repo_info##*$'\n'}" repo_info="${repo_info%$'\n'*}" local bare_repo="${repo_info##*$'\n'}" @@ -479,12 +481,25 @@ __git_ps1 () b="$(git symbolic-ref HEAD 2>/dev/null)" else local head="" - if ! __git_eread "$g/HEAD" head; then - return $exit - fi - # is it a symbolic ref? - b="${head#ref: }" - if [ "$head" = "$b" ]; then + + case "$ref_format" in + files) + if ! __git_eread "$g/HEAD" head; then + return $exit + fi + + if [[ $head == "ref: "* ]]; then + head="${head#ref: }" + else + head="" + fi + ;; + *) + head="$(git symbolic-ref HEAD 2>/dev/null)" + ;; + esac + + if test -z "$head"; then detached=yes b="$( case "${GIT_PS1_DESCRIBE_STYLE-}" in @@ -502,6 +517,8 @@ __git_ps1 () b="$short_sha..." b="($b)" + else + b="$head" fi fi fi diff --git a/contrib/credential/libsecret/git-credential-libsecret.c b/contrib/credential/libsecret/git-credential-libsecret.c index 215a81d8ba..90034d0cf1 100644 --- a/contrib/credential/libsecret/git-credential-libsecret.c +++ b/contrib/credential/libsecret/git-credential-libsecret.c @@ -164,6 +164,9 @@ static int keyring_get(struct credential *c) if (g_strv_length(parts) >= 1) { g_free(c->password); c->password = g_strdup(parts[0]); + } else { + g_free(c->password); + c->password = g_strdup(""); } for (int i = 1; i < g_strv_length(parts); i++) { if (g_str_has_prefix(parts[i], "password_expiry_utc=")) { diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c index 4cd56c42e2..4be0d58cd8 100644 --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c @@ -35,7 +35,7 @@ static void *xmalloc(size_t size) } static WCHAR *wusername, *password, *protocol, *host, *path, target[1024], - *password_expiry_utc; + *password_expiry_utc, *oauth_refresh_token; static void write_item(const char *what, LPCWSTR wbuf, int wlen) { @@ -140,6 +140,11 @@ static void get_credential(void) DWORD num_creds; int i; CREDENTIAL_ATTRIBUTEW *attr; + WCHAR *secret; + WCHAR *line; + WCHAR *remaining_lines; + WCHAR *part; + WCHAR *remaining_parts; if (!CredEnumerateW(L"git:*", 0, &num_creds, &creds)) return; @@ -149,9 +154,24 @@ static void get_credential(void) if (match_cred(creds[i], 0)) { write_item("username", creds[i]->UserName, creds[i]->UserName ? wcslen(creds[i]->UserName) : 0); - write_item("password", - (LPCWSTR)creds[i]->CredentialBlob, - creds[i]->CredentialBlobSize / sizeof(WCHAR)); + if (creds[i]->CredentialBlobSize > 0) { + secret = xmalloc(creds[i]->CredentialBlobSize); + wcsncpy_s(secret, creds[i]->CredentialBlobSize, (LPCWSTR)creds[i]->CredentialBlob, creds[i]->CredentialBlobSize / sizeof(WCHAR)); + line = wcstok_s(secret, L"\r\n", &remaining_lines); + write_item("password", line, line ? wcslen(line) : 0); + while(line != NULL) { + part = wcstok_s(line, L"=", &remaining_parts); + if (!wcscmp(part, L"oauth_refresh_token")) { + write_item("oauth_refresh_token", remaining_parts, remaining_parts ? wcslen(remaining_parts) : 0); + } + line = wcstok_s(NULL, L"\r\n", &remaining_lines); + } + free(secret); + } else { + write_item("password", + (LPCWSTR)creds[i]->CredentialBlob, + creds[i]->CredentialBlobSize / sizeof(WCHAR)); + } for (int j = 0; j < creds[i]->AttributeCount; j++) { attr = creds[i]->Attributes + j; if (!wcscmp(attr->Keyword, L"git_password_expiry_utc")) { @@ -170,16 +190,26 @@ static void store_credential(void) { CREDENTIALW cred; CREDENTIAL_ATTRIBUTEW expiry_attr; + WCHAR *secret; + int wlen; if (!wusername || !password) return; + if (oauth_refresh_token) { + wlen = _scwprintf(L"%s\r\noauth_refresh_token=%s", password, oauth_refresh_token); + secret = xmalloc(sizeof(WCHAR) * wlen); + _snwprintf_s(secret, sizeof(WCHAR) * wlen, wlen, L"%s\r\noauth_refresh_token=%s", password, oauth_refresh_token); + } else { + secret = _wcsdup(password); + } + cred.Flags = 0; cred.Type = CRED_TYPE_GENERIC; cred.TargetName = target; cred.Comment = L"saved by git-credential-wincred"; - cred.CredentialBlobSize = (wcslen(password)) * sizeof(WCHAR); - cred.CredentialBlob = (LPVOID)password; + cred.CredentialBlobSize = wcslen(secret) * sizeof(WCHAR); + cred.CredentialBlob = (LPVOID)_wcsdup(secret); cred.Persist = CRED_PERSIST_LOCAL_MACHINE; cred.AttributeCount = 0; cred.Attributes = NULL; @@ -194,6 +224,8 @@ static void store_credential(void) cred.TargetAlias = NULL; cred.UserName = wusername; + free(secret); + if (!CredWriteW(&cred, 0)) die("CredWrite failed"); } @@ -265,6 +297,8 @@ static void read_credential(void) password = utf8_to_utf16_dup(v); else if (!strcmp(buf, "password_expiry_utc")) password_expiry_utc = utf8_to_utf16_dup(v); + else if (!strcmp(buf, "oauth_refresh_token")) + oauth_refresh_token = utf8_to_utf16_dup(v); /* * Ignore other lines; we don't know what they mean, but * this future-proofs us when later versions of git do diff --git a/contrib/diff-highlight/DiffHighlight.pm b/contrib/diff-highlight/DiffHighlight.pm index 376f577737..636add6968 100644 --- a/contrib/diff-highlight/DiffHighlight.pm +++ b/contrib/diff-highlight/DiffHighlight.pm @@ -1,6 +1,6 @@ package DiffHighlight; -use 5.008; +use 5.008001; use warnings FATAL => 'all'; use strict; diff --git a/contrib/mw-to-git/Git/Mediawiki.pm b/contrib/mw-to-git/Git/Mediawiki.pm index 917d9e2d32..ff7811225e 100644 --- a/contrib/mw-to-git/Git/Mediawiki.pm +++ b/contrib/mw-to-git/Git/Mediawiki.pm @@ -1,6 +1,6 @@ package Git::Mediawiki; -use 5.008; +use 5.008001; use strict; use POSIX; use Git; diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index e0c5d3b0de..5dab3f506c 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -373,7 +373,8 @@ try_remove_previous () { # Usage: process_subtree_split_trailer SPLIT_HASH MAIN_HASH [REPOSITORY] process_subtree_split_trailer () { - assert test $# = 2 -o $# = 3 + assert test $# -ge 2 + assert test $# -le 3 b="$1" sq="$2" repository="" @@ -402,7 +403,8 @@ process_subtree_split_trailer () { # Usage: find_latest_squash DIR [REPOSITORY] find_latest_squash () { - assert test $# = 1 -o $# = 2 + assert test $# -ge 1 + assert test $# -le 2 dir="$1" repository="" if test "$#" = 2 @@ -455,7 +457,8 @@ find_latest_squash () { # Usage: find_existing_splits DIR REV [REPOSITORY] find_existing_splits () { - assert test $# = 2 -o $# = 3 + assert test $# -ge 2 + assert test $# -le 3 debug "Looking for prior splits..." local indent=$(($indent + 1)) @@ -489,13 +492,13 @@ find_existing_splits () { ;; END) debug "Main is: '$main'" - if test -z "$main" -a -n "$sub" + if test -z "$main" && test -n "$sub" then # squash commits refer to a subtree debug " Squash: $sq from $sub" cache_set "$sq" "$sub" fi - if test -n "$main" -a -n "$sub" + if test -n "$main" && test -n "$sub" then debug " Prior: $main -> $sub" cache_set $main $sub @@ -638,10 +641,16 @@ subtree_for_commit () { while read mode type tree name do assert test "$name" = "$dir" - assert test "$type" = "tree" -o "$type" = "commit" - test "$type" = "commit" && continue # ignore submodules - echo $tree - break + + case "$type" in + commit) + continue;; # ignore submodules + tree) + echo $tree + break;; + *) + die "fatal: tree entry is of type ${type}, expected tree or commit";; + esac done || exit $? } @@ -778,6 +787,22 @@ ensure_valid_ref_format () { die "fatal: '$1' does not look like a ref" } +# Usage: check if a commit from another subtree should be +# ignored from processing for splits +should_ignore_subtree_split_commit () { + assert test $# = 1 + local rev="$1" + if test -n "$(git log -1 --grep="git-subtree-dir:" $rev)" + then + if test -z "$(git log -1 --grep="git-subtree-mainline:" $rev)" && + test -z "$(git log -1 --grep="git-subtree-dir: $arg_prefix$" $rev)" + then + return 0 + fi + fi + return 1 +} + # Usage: process_split_commit REV PARENTS process_split_commit () { assert test $# = 2 @@ -916,7 +941,7 @@ cmd_split () { if test $# -eq 0 then rev=$(git rev-parse HEAD) - elif test $# -eq 1 -o $# -eq 2 + elif test $# -eq 1 || test $# -eq 2 then rev=$(git rev-parse -q --verify "$1^{commit}") || die "fatal: '$1' does not refer to a commit" @@ -963,7 +988,19 @@ cmd_split () { eval "$grl" | while read rev parents do - process_split_commit "$rev" "$parents" + if should_ignore_subtree_split_commit "$rev" + then + continue + fi + parsedparents='' + for parent in $parents + do + if ! should_ignore_subtree_split_commit "$parent" + then + parsedparents="$parsedparents$parent " + fi + done + process_split_commit "$rev" "$parsedparents" done || exit $? latest_new=$(cache_get latest_new) || exit $? @@ -1006,8 +1043,11 @@ cmd_split () { # Usage: cmd_merge REV [REPOSITORY] cmd_merge () { - test $# -eq 1 -o $# -eq 2 || + if test $# -lt 1 || test $# -gt 2 + then die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'" + fi + rev=$(git rev-parse -q --verify "$1^{commit}") || die "fatal: '$1' does not refer to a commit" repository="" diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index 49a21dd7c9..ca4df5be83 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -385,6 +385,46 @@ test_expect_success 'split sub dir/ with --rejoin' ' ) ' +# Tests that commits from other subtrees are not processed as +# part of a split. +# +# This test performs the following: +# - Creates Repo with subtrees 'subA' and 'subB' +# - Creates commits in the repo including changes to subtrees +# - Runs the following 'split' and commit' commands in order: +# - Perform 'split' on subtree A +# - Perform 'split' on subtree B +# - Create new commits with changes to subtree A and B +# - Perform split on subtree A +# - Check that the commits in subtree B are not processed +# as part of the subtree A split +test_expect_success 'split with multiple subtrees' ' + subtree_test_create_repo "$test_count" && + subtree_test_create_repo "$test_count/subA" && + subtree_test_create_repo "$test_count/subB" && + test_create_commit "$test_count" main1 && + test_create_commit "$test_count/subA" subA1 && + test_create_commit "$test_count/subA" subA2 && + test_create_commit "$test_count/subA" subA3 && + test_create_commit "$test_count/subB" subB1 && + git -C "$test_count" fetch ./subA HEAD && + git -C "$test_count" subtree add --prefix=subADir FETCH_HEAD && + git -C "$test_count" fetch ./subB HEAD && + git -C "$test_count" subtree add --prefix=subBDir FETCH_HEAD && + test_create_commit "$test_count" subADir/main-subA1 && + test_create_commit "$test_count" subBDir/main-subB1 && + git -C "$test_count" subtree split --prefix=subADir \ + --squash --rejoin -m "Sub A Split 1" && + git -C "$test_count" subtree split --prefix=subBDir \ + --squash --rejoin -m "Sub B Split 1" && + test_create_commit "$test_count" subADir/main-subA2 && + test_create_commit "$test_count" subBDir/main-subB2 && + git -C "$test_count" subtree split --prefix=subADir \ + --squash --rejoin -m "Sub A Split 2" && + test "$(git -C "$test_count" subtree split --prefix=subBDir \ + --squash --rejoin -d -m "Sub B Split 1" 2>&1 | grep -w "\[1\]")" = "" +' + test_expect_success 'split sub dir/ with --rejoin from scratch' ' subtree_test_create_repo "$test_count" && test_create_commit "$test_count" main1 && diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir index 888c34a521..989197aace 100755 --- a/contrib/workdir/git-new-workdir +++ b/contrib/workdir/git-new-workdir @@ -79,7 +79,7 @@ trap cleanup $siglist # create the links to the original repo. explicitly exclude index, HEAD and # logs/HEAD from the list since they are purely related to the current working # directory, and should not be shared. -for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn +for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn reftable do # create a containing directory if needed case $x in @@ -1028,7 +1028,7 @@ static int read_convert_config(const char *var, const char *value, if (parse_config_key(var, "filter", &name, &namelen, &key) < 0 || !name) return 0; for (drv = user_convert; drv; drv = drv->next) - if (!strncmp(drv->name, name, namelen) && !drv->name[namelen]) + if (!xstrncmpz(drv->name, name, namelen)) break; if (!drv) { CALLOC_ARRAY(drv, 1); @@ -92,7 +92,7 @@ void convert_attrs(struct index_state *istate, struct conv_attrs *ca, const char *path); extern enum eol core_eol; -extern char *check_roundtrip_encoding; +extern const char *check_roundtrip_encoding; const char *get_cached_convert_stats_ascii(struct index_state *istate, const char *path); const char *get_wt_convert_stats_ascii(const char *path); diff --git a/delta-islands.c b/delta-islands.c index 5de5759f3f..ee2318d45a 100644 --- a/delta-islands.c +++ b/delta-islands.c @@ -1,18 +1,13 @@ #include "git-compat-util.h" -#include "attr.h" #include "object.h" -#include "blob.h" #include "commit.h" #include "gettext.h" #include "hex.h" #include "tag.h" #include "tree.h" -#include "delta.h" #include "pack.h" #include "tree-walk.h" #include "diff.h" -#include "revision.h" -#include "list-objects.h" #include "progress.h" #include "refs.h" #include "khash.h" diff --git a/diff-lib.c b/diff-lib.c index 0e9ec4f68a..6c8df04273 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -2,7 +2,6 @@ * Copyright (C) 2005 Junio C Hamano */ #include "git-compat-util.h" -#include "quote.h" #include "commit.h" #include "diff.h" #include "diffcore.h" @@ -38,7 +37,13 @@ */ static int check_removed(const struct cache_entry *ce, struct stat *st) { - if (lstat(ce->name, st) < 0) { + int stat_err; + + if (!(ce->ce_flags & CE_FSMONITOR_VALID)) + stat_err = lstat(ce->name, st); + else + stat_err = fake_lstat(ce, st); + if (stat_err < 0) { if (!is_missing_file_error(errno)) return -1; return 1; diff --git a/diff-no-index.c b/diff-no-index.c index e7041b89e3..3a8965672c 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -8,13 +8,10 @@ #include "abspath.h" #include "color.h" #include "commit.h" -#include "blob.h" -#include "tag.h" #include "diff.h" #include "diffcore.h" #include "gettext.h" #include "revision.h" -#include "log-tree.h" #include "parse-options.h" #include "string-list.h" #include "dir.h" @@ -16,12 +16,10 @@ #include "hex.h" #include "xdiff-interface.h" #include "color.h" -#include "attr.h" #include "run-command.h" #include "utf8.h" #include "object-store-ll.h" #include "userdiff.h" -#include "submodule-config.h" #include "submodule.h" #include "hashmap.h" #include "mem-pool.h" @@ -372,7 +370,10 @@ int git_diff_ui_config(const char *var, const char *value, return 0; } if (!strcmp(var, "diff.colormovedws")) { - unsigned cm = parse_color_moved_ws(value); + unsigned cm; + if (!value) + return config_error_nonbool(var); + cm = parse_color_moved_ws(value); if (cm & COLOR_MOVED_WS_ERROR) return -1; diff_color_moved_ws_default = cm; @@ -426,10 +427,15 @@ int git_diff_ui_config(const char *var, const char *value, if (!strcmp(var, "diff.orderfile")) return git_config_pathname(&diff_order_file_cfg, var, value); - if (!strcmp(var, "diff.ignoresubmodules")) + if (!strcmp(var, "diff.ignoresubmodules")) { + if (!value) + return config_error_nonbool(var); handle_ignore_submodules_arg(&default_diff_options, value); + } if (!strcmp(var, "diff.submodule")) { + if (!value) + return config_error_nonbool(var); if (parse_submodule_params(&default_diff_options, value)) warning(_("Unknown value for 'diff.submodule' config variable: '%s'"), value); @@ -437,9 +443,12 @@ int git_diff_ui_config(const char *var, const char *value, } if (!strcmp(var, "diff.algorithm")) { + if (!value) + return config_error_nonbool(var); diff_algorithm = parse_algorithm_value(value); if (diff_algorithm < 0) - return -1; + return error(_("unknown value for config '%s': %s"), + var, value); return 0; } @@ -473,9 +482,13 @@ int git_diff_basic_config(const char *var, const char *value, } if (!strcmp(var, "diff.wserrorhighlight")) { - int val = parse_ws_error_highlight(value); + int val; + if (!value) + return config_error_nonbool(var); + val = parse_ws_error_highlight(value); if (val < 0) - return -1; + return error(_("unknown value for config '%s': %s"), + var, value); ws_error_highlight_default = val; return 0; } @@ -490,6 +503,8 @@ int git_diff_basic_config(const char *var, const char *value, if (!strcmp(var, "diff.dirstat")) { struct strbuf errmsg = STRBUF_INIT; + if (!value) + return config_error_nonbool(var); default_diff_options.dirstat_permille = diff_dirstat_permille_default; if (parse_dirstat_params(&default_diff_options, value, &errmsg)) warning(_("Found errors in 'diff.dirstat' config variable:\n%s"), @@ -4369,7 +4384,8 @@ static void run_external_diff(const char *pgm, add_external_diff_name(o->repo, &cmd.args, two); if (other) { strvec_push(&cmd.args, other); - strvec_push(&cmd.args, xfrm_msg); + if (xfrm_msg) + strvec_push(&cmd.args, xfrm_msg); } } @@ -5574,7 +5590,7 @@ struct option *add_diff_options(const struct option *opts, OPT_BITOP(0, "shortstat", &options->output_format, N_("output only the last line of --stat"), DIFF_FORMAT_SHORTSTAT, DIFF_FORMAT_NO_OUTPUT), - OPT_CALLBACK_F('X', "dirstat", options, N_("<param1,param2>..."), + OPT_CALLBACK_F('X', "dirstat", options, N_("<param1>,<param2>..."), N_("output the distribution of relative amount of changes for each sub-directory"), PARSE_OPT_NONEG | PARSE_OPT_OPTARG, diff_opt_dirstat), @@ -5582,8 +5598,8 @@ struct option *add_diff_options(const struct option *opts, N_("synonym for --dirstat=cumulative"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, diff_opt_dirstat), - OPT_CALLBACK_F(0, "dirstat-by-file", options, N_("<param1,param2>..."), - N_("synonym for --dirstat=files,param1,param2..."), + OPT_CALLBACK_F(0, "dirstat-by-file", options, N_("<param1>,<param2>..."), + N_("synonym for --dirstat=files,<param1>,<param2>..."), PARSE_OPT_NONEG | PARSE_OPT_OPTARG, diff_opt_dirstat), OPT_BIT_F(0, "check", &options->output_format, diff --git a/diffcore-break.c b/diffcore-break.c index f57ece2757..49ba38aa7c 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -2,7 +2,6 @@ * Copyright (C) 2005 Junio C Hamano */ #include "git-compat-util.h" -#include "diff.h" #include "diffcore.h" #include "hash.h" #include "object.h" diff --git a/diffcore-delta.c b/diffcore-delta.c index c30b56e983..ba6cbee76b 100644 --- a/diffcore-delta.c +++ b/diffcore-delta.c @@ -1,5 +1,4 @@ #include "git-compat-util.h" -#include "diff.h" #include "diffcore.h" /* @@ -159,6 +158,10 @@ static struct spanhash_top *hash_chars(struct repository *r, n = 0; accum1 = accum2 = 0; } + if (n > 0) { + hashval = (accum1 + accum2 * 0x61) % HASHBASE; + hash = add_spanhash(hash, hashval, n); + } QSORT(hash->data, (size_t)1ul << hash->alloc_log2, spanhash_cmp); return hash; } diff --git a/dir-iterator.c b/dir-iterator.c index 278b04243a..de619846f2 100644 --- a/dir-iterator.c +++ b/dir-iterator.c @@ -2,11 +2,20 @@ #include "dir.h" #include "iterator.h" #include "dir-iterator.h" +#include "string-list.h" struct dir_iterator_level { DIR *dir; /* + * The directory entries of the current level. This list will only be + * populated when the iterator is ordered. In that case, `dir` will be + * set to `NULL`. + */ + struct string_list entries; + size_t entries_idx; + + /* * The length of the directory part of path at this level * (including a trailing '/'): */ @@ -43,6 +52,31 @@ struct dir_iterator_int { unsigned int flags; }; +static int next_directory_entry(DIR *dir, const char *path, + struct dirent **out) +{ + struct dirent *de; + +repeat: + errno = 0; + de = readdir(dir); + if (!de) { + if (errno) { + warning_errno("error reading directory '%s'", + path); + return -1; + } + + return 1; + } + + if (is_dot_or_dotdot(de->d_name)) + goto repeat; + + *out = de; + return 0; +} + /* * Push a level in the iter stack and initialize it with information from * the directory pointed by iter->base->path. It is assumed that this @@ -72,6 +106,35 @@ static int push_level(struct dir_iterator_int *iter) return -1; } + string_list_init_dup(&level->entries); + level->entries_idx = 0; + + /* + * When the iterator is sorted we read and sort all directory entries + * directly. + */ + if (iter->flags & DIR_ITERATOR_SORTED) { + struct dirent *de; + + while (1) { + int ret = next_directory_entry(level->dir, iter->base.path.buf, &de); + if (ret < 0) { + if (errno != ENOENT && + iter->flags & DIR_ITERATOR_PEDANTIC) + return -1; + continue; + } else if (ret > 0) { + break; + } + + string_list_append(&level->entries, de->d_name); + } + string_list_sort(&level->entries); + + closedir(level->dir); + level->dir = NULL; + } + return 0; } @@ -88,21 +151,22 @@ static int pop_level(struct dir_iterator_int *iter) warning_errno("error closing directory '%s'", iter->base.path.buf); level->dir = NULL; + string_list_clear(&level->entries, 0); return --iter->levels_nr; } /* * Populate iter->base with the necessary information on the next iteration - * entry, represented by the given dirent de. Return 0 on success and -1 + * entry, represented by the given name. Return 0 on success and -1 * otherwise, setting errno accordingly. */ static int prepare_next_entry_data(struct dir_iterator_int *iter, - struct dirent *de) + const char *name) { int err, saved_errno; - strbuf_addstr(&iter->base.path, de->d_name); + strbuf_addstr(&iter->base.path, name); /* * We have to reset these because the path strbuf might have * been realloc()ed at the previous strbuf_addstr(). @@ -139,27 +203,34 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) struct dirent *de; struct dir_iterator_level *level = &iter->levels[iter->levels_nr - 1]; + const char *name; strbuf_setlen(&iter->base.path, level->prefix_len); - errno = 0; - de = readdir(level->dir); - if (!de) { - if (errno) { - warning_errno("error reading directory '%s'", - iter->base.path.buf); + if (level->dir) { + int ret = next_directory_entry(level->dir, iter->base.path.buf, &de); + if (ret < 0) { if (iter->flags & DIR_ITERATOR_PEDANTIC) goto error_out; - } else if (pop_level(iter) == 0) { - return dir_iterator_abort(dir_iterator); + continue; + } else if (ret > 0) { + if (pop_level(iter) == 0) + return dir_iterator_abort(dir_iterator); + continue; } - continue; - } - if (is_dot_or_dotdot(de->d_name)) - continue; + name = de->d_name; + } else { + if (level->entries_idx >= level->entries.nr) { + if (pop_level(iter) == 0) + return dir_iterator_abort(dir_iterator); + continue; + } - if (prepare_next_entry_data(iter, de)) { + name = level->entries.items[level->entries_idx++].string; + } + + if (prepare_next_entry_data(iter, name)) { if (errno != ENOENT && iter->flags & DIR_ITERATOR_PEDANTIC) goto error_out; continue; @@ -188,6 +259,8 @@ int dir_iterator_abort(struct dir_iterator *dir_iterator) warning_errno("error closing directory '%s'", iter->base.path.buf); } + + string_list_clear(&level->entries, 0); } free(iter->levels); diff --git a/dir-iterator.h b/dir-iterator.h index 479e1ec784..6d438809b6 100644 --- a/dir-iterator.h +++ b/dir-iterator.h @@ -54,8 +54,11 @@ * and ITER_ERROR is returned immediately. In both cases, a meaningful * warning is emitted. Note: ENOENT errors are always ignored so that * the API users may remove files during iteration. + * + * - DIR_ITERATOR_SORTED: sort directory entries alphabetically. */ #define DIR_ITERATOR_PEDANTIC (1 << 0) +#define DIR_ITERATOR_SORTED (1 << 1) struct dir_iterator { /* The current path: */ @@ -16,7 +16,6 @@ #include "object-file.h" #include "object-store-ll.h" #include "path.h" -#include "attr.h" #include "refs.h" #include "wildmatch.h" #include "pathspec.h" @@ -2179,7 +2178,8 @@ static int exclude_matches_pathspec(const char *path, int pathlen, PATHSPEC_LITERAL | PATHSPEC_GLOB | PATHSPEC_ICASE | - PATHSPEC_EXCLUDE); + PATHSPEC_EXCLUDE | + PATHSPEC_ATTR); for (i = 0; i < pathspec->nr; i++) { const struct pathspec_item *item = &pathspec->items[i]; @@ -1,5 +1,4 @@ #include "git-compat-util.h" -#include "blob.h" #include "object-store-ll.h" #include "dir.h" #include "environment.h" diff --git a/environment.c b/environment.c index 9e37bf58c0..90632a39bc 100644 --- a/environment.c +++ b/environment.c @@ -64,7 +64,7 @@ const char *excludes_file; enum auto_crlf auto_crlf = AUTO_CRLF_FALSE; enum eol core_eol = EOL_UNSET; int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; -char *check_roundtrip_encoding = "SHIFT-JIS"; +const char *check_roundtrip_encoding = "SHIFT-JIS"; enum branch_track git_branch_track = BRANCH_TRACK_REMOTE; enum rebase_setup_type autorebase = AUTOREBASE_NEVER; enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED; diff --git a/ewah/bitmap.c b/ewah/bitmap.c index 7b525b1ecd..ac7e0af622 100644 --- a/ewah/bitmap.c +++ b/ewah/bitmap.c @@ -169,6 +169,15 @@ size_t bitmap_popcount(struct bitmap *self) return count; } +int bitmap_is_empty(struct bitmap *self) +{ + size_t i; + for (i = 0; i < self->word_alloc; i++) + if (self->words[i]) + return 0; + return 1; +} + int bitmap_equals(struct bitmap *self, struct bitmap *other) { struct bitmap *big, *small; diff --git a/ewah/ewok.h b/ewah/ewok.h index 7eb8b9b630..c11d76c6f3 100644 --- a/ewah/ewok.h +++ b/ewah/ewok.h @@ -189,5 +189,6 @@ void bitmap_or_ewah(struct bitmap *self, struct ewah_bitmap *other); void bitmap_or(struct bitmap *self, const struct bitmap *other); size_t bitmap_popcount(struct bitmap *self); +int bitmap_is_empty(struct bitmap *self); #endif diff --git a/exec-cmd.c b/exec-cmd.c index 1d597e84ea..909777f61f 100644 --- a/exec-cmd.c +++ b/exec-cmd.c @@ -4,7 +4,6 @@ #include "exec-cmd.h" #include "gettext.h" #include "path.h" -#include "quote.h" #include "run-command.h" #include "strvec.h" #include "trace.h" diff --git a/fetch-pack.c b/fetch-pack.c index 26999e3b65..091f9a80a9 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -10,7 +10,6 @@ #include "pkt-line.h" #include "commit.h" #include "tag.h" -#include "exec-cmd.h" #include "pack.h" #include "sideband.h" #include "fetch-pack.h" @@ -18,7 +17,6 @@ #include "run-command.h" #include "connect.h" #include "trace2.h" -#include "transport.h" #include "version.h" #include "oid-array.h" #include "oidset.h" @@ -1862,6 +1860,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, static int fetch_pack_config_cb(const char *var, const char *value, const struct config_context *ctx, void *cb) { + const char *msg_id; + if (strcmp(var, "fetch.fsck.skiplist") == 0) { const char *path; @@ -1873,12 +1873,14 @@ static int fetch_pack_config_cb(const char *var, const char *value, return 0; } - if (skip_prefix(var, "fetch.fsck.", &var)) { - if (is_valid_msg_type(var, value)) + if (skip_prefix(var, "fetch.fsck.", &msg_id)) { + if (!value) + return config_error_nonbool(var); + if (is_valid_msg_type(msg_id, value)) strbuf_addf(&fsck_msg_types, "%c%s=%s", - fsck_msg_types.len ? ',' : '=', var, value); + fsck_msg_types.len ? ',' : '=', msg_id, value); else - warning("Skipping unknown msg id '%s'", var); + warning("Skipping unknown msg id '%s'", msg_id); return 0; } @@ -2214,7 +2216,7 @@ void negotiate_using_fetch(const struct oid_array *negotiation_tips, the_repository, "%d", negotiation_round); } - trace2_region_enter("fetch-pack", "negotiate_using_fetch", the_repository); + trace2_region_leave("fetch-pack", "negotiate_using_fetch", the_repository); trace2_data_intmax("negotiate_using_fetch", the_repository, "total_rounds", negotiation_round); clear_common_flag(acked_commits); diff --git a/fetch-pack.h b/fetch-pack.h index 8c7752fc82..6775d26517 100644 --- a/fetch-pack.h +++ b/fetch-pack.h @@ -2,7 +2,6 @@ #define FETCH_PACK_H #include "string-list.h" -#include "run-command.h" #include "protocol.h" #include "list-objects-filter-options.h" #include "oidset.h" @@ -16,12 +16,10 @@ #include "refs.h" #include "url.h" #include "utf8.h" -#include "decorate.h" #include "oidset.h" #include "packfile.h" #include "submodule-config.h" #include "config.h" -#include "credential.h" #include "help.h" static ssize_t max_tree_entry_len = 4096; @@ -1048,138 +1046,6 @@ done: return ret; } -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); -} - -static int submodule_url_is_relative(const char *url) -{ - return starts_with_dot_slash(url) || starts_with_dot_dot_slash(url); -} - -/* - * Count directory components that a relative submodule URL should chop - * from the remote_url it is to be resolved against. - * - * In other words, this counts "../" components at the start of a - * submodule URL. - * - * Returns the number of directory components to chop and writes a - * pointer to the next character of url after all leading "./" and - * "../" components to out. - */ -static int count_leading_dotdots(const char *url, const char **out) -{ - int result = 0; - while (1) { - if (starts_with_dot_dot_slash(url)) { - result++; - url += strlen("../"); - continue; - } - if (starts_with_dot_slash(url)) { - url += strlen("./"); - continue; - } - *out = url; - return result; - } -} -/* - * Check whether a transport is implemented by git-remote-curl. - * - * If it is, returns 1 and writes the URL that would be passed to - * git-remote-curl to the "out" parameter. - * - * Otherwise, returns 0 and leaves "out" untouched. - * - * Examples: - * http::https://example.com/repo.git -> 1, https://example.com/repo.git - * https://example.com/repo.git -> 1, https://example.com/repo.git - * git://example.com/repo.git -> 0 - * - * This is for use in checking for previously exploitable bugs that - * required a submodule URL to be passed to git-remote-curl. - */ -static int url_to_curl_url(const char *url, const char **out) -{ - /* - * We don't need to check for case-aliases, "http.exe", and so - * on because in the default configuration, is_transport_allowed - * prevents URLs with those schemes from being cloned - * automatically. - */ - if (skip_prefix(url, "http::", out) || - skip_prefix(url, "https::", out) || - skip_prefix(url, "ftp::", out) || - skip_prefix(url, "ftps::", out)) - return 1; - if (starts_with(url, "http://") || - starts_with(url, "https://") || - starts_with(url, "ftp://") || - starts_with(url, "ftps://")) { - *out = url; - return 1; - } - return 0; -} - -static int check_submodule_url(const char *url) -{ - const char *curl_url; - - if (looks_like_command_line_option(url)) - return -1; - - if (submodule_url_is_relative(url) || starts_with(url, "git://")) { - char *decoded; - const char *next; - int has_nl; - - /* - * This could be appended to an http URL and url-decoded; - * check for malicious characters. - */ - decoded = url_decode(url); - has_nl = !!strchr(decoded, '\n'); - - free(decoded); - if (has_nl) - return -1; - - /* - * URLs which escape their root via "../" can overwrite - * the host field and previous components, resolving to - * URLs like https::example.com/submodule.git and - * https:///example.com/submodule.git that were - * susceptible to CVE-2020-11008. - */ - if (count_leading_dotdots(url, &next) > 0 && - (*next == ':' || *next == '/')) - return -1; - } - - else if (url_to_curl_url(url, &curl_url)) { - struct credential c = CREDENTIAL_INIT; - int ret = 0; - if (credential_from_url_gently(&c, curl_url, 1) || - !*c.host) - ret = -1; - credential_clear(&c); - return ret; - } - - return 0; -} - struct fsck_gitmodules_data { const struct object_id *oid; struct fsck_options *options; @@ -1403,6 +1269,8 @@ int git_fsck_config(const char *var, const char *value, const struct config_context *ctx, void *cb) { struct fsck_options *options = cb; + const char *msg_id; + if (strcmp(var, "fsck.skiplist") == 0) { const char *path; struct strbuf sb = STRBUF_INIT; @@ -1416,8 +1284,10 @@ int git_fsck_config(const char *var, const char *value, return 0; } - if (skip_prefix(var, "fsck.", &var)) { - fsck_set_msg_type(options, var, value); + if (skip_prefix(var, "fsck.", &msg_id)) { + if (!value) + return config_error_nonbool(var); + fsck_set_msg_type(options, msg_id, value); return 0; } diff --git a/fsmonitor--daemon.h b/fsmonitor--daemon.h index 673f80d2aa..5cbbec8d94 100644 --- a/fsmonitor--daemon.h +++ b/fsmonitor--daemon.h @@ -3,9 +3,7 @@ #ifdef HAVE_FSMONITOR_DAEMON_BACKEND -#include "dir.h" -#include "run-command.h" -#include "simple-ipc.h" +#include "hashmap.h" #include "thread-utils.h" #include "fsmonitor-path-utils.h" diff --git a/fsmonitor-ipc.c b/fsmonitor-ipc.c index 153918cf76..45471b5b74 100644 --- a/fsmonitor-ipc.c +++ b/fsmonitor-ipc.c @@ -1,5 +1,4 @@ #include "git-compat-util.h" -#include "fsmonitor-ll.h" #include "gettext.h" #include "simple-ipc.h" #include "fsmonitor-ipc.h" @@ -7,9 +7,7 @@ #include "environment.h" #include "exec-cmd.h" #include "gettext.h" -#include "strbuf.h" #include "utf8.h" -#include "config.h" #ifndef NO_GETTEXT # include <libintl.h> diff --git a/git-archimport.perl b/git-archimport.perl index b7c173c345..f5a317b899 100755 --- a/git-archimport.perl +++ b/git-archimport.perl @@ -54,7 +54,7 @@ and can contain multiple, unrelated branches. =cut -use 5.008; +use 5.008001; use strict; use warnings; use Getopt::Std; diff --git a/git-compat-util.h b/git-compat-util.h index 3e7a59b5ff..7c2a6538e5 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -225,6 +225,7 @@ struct strbuf; #include <stddef.h> #include <stdlib.h> #include <stdarg.h> +#include <stdbool.h> #include <string.h> #ifdef HAVE_STRINGS_H #include <strings.h> /* for strcasecmp() */ @@ -684,11 +685,11 @@ report_fn get_warn_routine(void); void set_die_is_recursing_routine(int (*routine)(void)); /* - * If the string "str" begins with the string found in "prefix", return 1. + * If the string "str" begins with the string found in "prefix", return true. * The "out" parameter is set to "str + strlen(prefix)" (i.e., to the point in * the string right after the prefix). * - * Otherwise, return 0 and leave "out" untouched. + * Otherwise, return false and leave "out" untouched. * * Examples: * @@ -699,57 +700,58 @@ void set_die_is_recursing_routine(int (*routine)(void)); * [skip prefix if present, otherwise use whole string] * skip_prefix(name, "refs/heads/", &name); */ -static inline int skip_prefix(const char *str, const char *prefix, - const char **out) +static inline bool skip_prefix(const char *str, const char *prefix, + const char **out) { do { if (!*prefix) { *out = str; - return 1; + return true; } } while (*str++ == *prefix++); - return 0; + return false; } /* * Like skip_prefix, but promises never to read past "len" bytes of the input * buffer, and returns the remaining number of bytes in "out" via "outlen". */ -static inline int skip_prefix_mem(const char *buf, size_t len, - const char *prefix, - const char **out, size_t *outlen) +static inline bool skip_prefix_mem(const char *buf, size_t len, + const char *prefix, + const char **out, size_t *outlen) { size_t prefix_len = strlen(prefix); if (prefix_len <= len && !memcmp(buf, prefix, prefix_len)) { *out = buf + prefix_len; *outlen = len - prefix_len; - return 1; + return true; } - return 0; + return false; } /* - * If buf ends with suffix, return 1 and subtract the length of the suffix - * from *len. Otherwise, return 0 and leave *len untouched. + * If buf ends with suffix, return true and subtract the length of the suffix + * from *len. Otherwise, return false and leave *len untouched. */ -static inline int strip_suffix_mem(const char *buf, size_t *len, - const char *suffix) +static inline bool strip_suffix_mem(const char *buf, size_t *len, + const char *suffix) { size_t suflen = strlen(suffix); if (*len < suflen || memcmp(buf + (*len - suflen), suffix, suflen)) - return 0; + return false; *len -= suflen; - return 1; + return true; } /* - * If str ends with suffix, return 1 and set *len to the size of the string - * without the suffix. Otherwise, return 0 and set *len to the size of the + * If str ends with suffix, return true and set *len to the size of the string + * without the suffix. Otherwise, return false and set *len to the size of the * string. * * Note that we do _not_ NUL-terminate str to the new length. */ -static inline int strip_suffix(const char *str, const char *suffix, size_t *len) +static inline bool strip_suffix(const char *str, const char *suffix, + size_t *len) { *len = strlen(str); return strip_suffix_mem(str, len, suffix); @@ -1013,6 +1015,15 @@ static inline unsigned long cast_size_t_to_ulong(size_t a) return (unsigned long)a; } +static inline uint32_t cast_size_t_to_uint32_t(size_t a) +{ + if (a != (uint32_t)a) + die("object too large to read on this platform: %" + PRIuMAX" is cut off to %u", + (uintmax_t)a, (uint32_t)a); + return (uint32_t)a; +} + static inline int cast_size_t_to_int(size_t a) { if (a > INT_MAX) diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 289d4bc684..1e03ba94d1 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -1,6 +1,6 @@ #!/usr/bin/perl -use 5.008; +use 5.008001; use strict; use warnings; use Getopt::Std; diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 7bf3c12d67..211ec8459a 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -13,7 +13,7 @@ # The head revision is on branch "origin" by default. # You can change that with the '-o' option. -use 5.008; +use 5.008001; use strict; use warnings; use Getopt::Long; @@ -329,7 +329,7 @@ sub conn { # Use a HTTP Proxy. Only works for HTTP proxies that # don't require user authentication # - # See: http://www.ietf.org/rfc/rfc2817.txt + # See: https://www.ietf.org/rfc/rfc2817.txt $s = IO::Socket::INET->new(PeerHost => $proxyhost, PeerPort => $proxyport); die "Socket to $proxyhost: $!\n" unless defined $s; diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 7b757360e2..124f598bdc 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -15,7 +15,7 @@ #### #### -use 5.008; +use 5.008001; use strict; use warnings; use bytes; diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index e4e820e680..dd0c9a5b7f 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -91,6 +91,19 @@ then # ignore the error from the above --- run_merge_tool # will diagnose unusable tool by itself run_merge_tool "$merge_tool" false + + status=$? + if test $status -ge 126 + then + # Command not found (127), not executable (126) or + # exited via a signal (>= 128). + exit $status + fi + + if test "$GIT_DIFFTOOL_TRUST_EXIT_CODE" = true + then + exit $status + fi else # Launch the merge tool on each path provided by 'git diff' while test $# -gt 6 diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 3e5907a460..507fb2b682 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -24,7 +24,7 @@ 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/>.}] +along with this program; if not, see <https://www.gnu.org/licenses/>.}] ###################################################################### ## @@ -2367,7 +2367,7 @@ proc do_quit {{rc {1}}} { set ret_code $rc # Briefly enable send again, working around Tk bug - # http://sourceforge.net/tracker/?func=detail&atid=112997&aid=1821174&group_id=12997 + # https://sourceforge.net/p/tktoolkit/bugs/2343/ tk appname [appname] destroy . @@ -3052,7 +3052,7 @@ if {$doc_path ne {}} { if {[file isfile $doc_path]} { set doc_url "file:$doc_path" } else { - set doc_url {http://www.kernel.org/pub/software/scm/git/docs/} + set doc_url {https://www.kernel.org/pub/software/scm/git/docs/} } proc start_browser {url} { diff --git a/git-gui/lib/encoding.tcl b/git-gui/lib/encoding.tcl index 32668fc9c6..d2e0fa60c3 100644 --- a/git-gui/lib/encoding.tcl +++ b/git-gui/lib/encoding.tcl @@ -3,7 +3,7 @@ # (Copied from gitk, commit fd8ccbec4f0161) # This list of encoding names and aliases is distilled from -# http://www.iana.org/assignments/character-sets. +# https://www.iana.org/assignments/character-sets. # Not all of them are supported by Tcl. set encoding_aliases { { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII diff --git a/git-gui/po/README b/git-gui/po/README index 2514bc22ab..116233100d 100644 --- a/git-gui/po/README +++ b/git-gui/po/README @@ -39,7 +39,7 @@ in your language? If you do not know what your language should be named, you need to find it. This currently follows ISO 639-1 two letter codes: - http://www.loc.gov/standards/iso639-2/php/code_list.php + https://www.loc.gov/standards/iso639-2/php/code_list.php For example, if you are preparing a translation for Afrikaans, the language code is "af". If there already is a translation for your diff --git a/git-instaweb.sh b/git-instaweb.sh index c68f49454c..994431c887 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -432,7 +432,7 @@ mongoose_conf() { # Mongoose web server configuration file. # Lines starting with '#' and empty lines are ignored. # For detailed description of every option, visit -# http://code.google.com/p/mongoose/wiki/MongooseManual +# https://code.google.com/p/mongoose/wiki/MongooseManual root $root ports $port @@ -458,7 +458,7 @@ plackup_conf () { #!$PERL # gitweb - simple web interface to track changes in git repositories -# PSGI wrapper and server starter (see http://plackperl.org) +# PSGI wrapper and server starter (see https://plackperl.org) use strict; @@ -689,8 +689,8 @@ def setP4ExecBit(file, mode): if not isModeExec(mode): p4Type = getP4OpenedType(file) - p4Type = re.sub('^([cku]?)x(.*)', '\\1\\2', p4Type) - p4Type = re.sub('(.*?\+.*?)x(.*?)', '\\1\\2', p4Type) + p4Type = re.sub(r'^([cku]?)x(.*)', r'\1\2', p4Type) + p4Type = re.sub(r'(.*?\+.*?)x(.*?)', r'\1\2', p4Type) if p4Type[-1] == "+": p4Type = p4Type[0:-1] @@ -701,7 +701,7 @@ def getP4OpenedType(file): """Returns the perforce file type for the given file.""" result = p4_read_pipe(["opened", wildcard_encode(file)]) - match = re.match(".*\((.+)\)( \*exclusive\*)?\r?$", result) + match = re.match(r".*\((.+)\)( \*exclusive\*)?\r?$", result) if match: return match.group(1) else: @@ -757,7 +757,7 @@ def parseDiffTreeEntry(entry): global _diff_tree_pattern if not _diff_tree_pattern: - _diff_tree_pattern = re.compile(':(\d+) (\d+) (\w+) (\w+) ([A-Z])(\d+)?\t(.*?)((\t(.*))|$)') + _diff_tree_pattern = re.compile(r':(\d+) (\d+) (\w+) (\w+) ([A-Z])(\d+)?\t(.*?)((\t(.*))|$)') match = _diff_tree_pattern.match(entry) if match: @@ -918,9 +918,9 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False, if len(result) > 0: data = result[0].get('data') if data: - m = re.search('Too many rows scanned \(over (\d+)\)', data) + m = re.search(r'Too many rows scanned \(over (\d+)\)', data) if not m: - m = re.search('Request too large \(over (\d+)\)', data) + m = re.search(r'Request too large \(over (\d+)\)', data) if m: limit = int(m.group(1)) @@ -1452,7 +1452,7 @@ def wildcard_encode(path): def wildcard_present(path): - m = re.search("[*#@%]", path) + m = re.search(r"[*#@%]", path) return m is not None @@ -3048,7 +3048,7 @@ class P4Sync(Command, P4UserMap): # Preserve everything in relative path name except leading # //depot/; just look at first prefix as they all should # be in the same depot. - depot = re.sub("^(//[^/]+/).*", r'\1', prefixes[0]) + depot = re.sub(r"^(//[^/]+/).*", r'\1', prefixes[0]) if p4PathStartsWith(path, depot): path = path[len(depot):] @@ -3603,7 +3603,7 @@ class P4Sync(Command, P4UserMap): commitFound = True else: gitCommit = read_pipe(["git", "rev-list", "--max-count=1", - "--reverse", ":/\[git-p4:.*change = %d\]" % changelist], ignore_error=True) + "--reverse", r":/\[git-p4:.*change = %d\]" % changelist], ignore_error=True) if len(gitCommit) == 0: print("importing label %s: could not find git commit for changelist %d" % (name, changelist)) else: @@ -4182,7 +4182,7 @@ class P4Sync(Command, P4UserMap): if len(self.changesFile) == 0: revision = "#head" - p = re.sub("\.\.\.$", "", p) + p = re.sub(r"\.\.\.$", "", p) if not p.endswith("/"): p += "/" @@ -4251,7 +4251,8 @@ class P4Sync(Command, P4UserMap): if self.tempBranches != []: for branch in self.tempBranches: read_pipe(["git", "update-ref", "-d", branch]) - os.rmdir(os.path.join(os.environ.get("GIT_DIR", ".git"), self.tempBranchLocation)) + if len(read_pipe(["git", "for-each-ref", self.tempBranchLocation])) > 0: + die("There are unexpected temporary branches") # Create a symbolic ref p4/HEAD pointing to p4/<branch> to allow # a convenient shortcut refname "p4". @@ -4291,7 +4292,7 @@ class P4Rebase(Command): die("Cannot find upstream branchpoint for rebase") # the branchpoint may be p4/foo~3, so strip off the parent - upstream = re.sub("~[0-9]+$", "", upstream) + upstream = re.sub(r"~[0-9]+$", "", upstream) print("Rebasing the current branch onto %s" % upstream) oldHead = read_pipe(["git", "rev-parse", "HEAD"]).strip() @@ -4320,8 +4321,8 @@ class P4Clone(P4Sync): def defaultDestination(self, args): # TODO: use common prefix of args? depotPath = args[0] - depotDir = re.sub("(@[^@]*)$", "", depotPath) - depotDir = re.sub("(#[^#]*)$", "", depotDir) + depotDir = re.sub(r"(@[^@]*)$", "", depotPath) + depotDir = re.sub(r"(#[^#]*)$", "", depotDir) depotDir = re.sub(r"\.\.\.$", "", depotDir) depotDir = re.sub(r"/$", "", depotDir) return os.path.split(depotDir)[1] diff --git a/git-send-email.perl b/git-send-email.perl index cacdbd6bb2..821b2b3a13 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -16,7 +16,7 @@ # and second line is the subject of the message. # -use 5.008; +use 5.008001; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); use Getopt::Long; @@ -28,8 +28,8 @@ Getopt::Long::Configure qw/ pass_through /; sub usage { print <<EOT; -git send-email' [<options>] <file|directory> -git send-email' [<options>] <format-patch options> +git send-email [<options>] <file|directory> +git send-email [<options>] <format-patch options> git send-email --dump-aliases Composing: @@ -119,13 +119,16 @@ sub completion_helper { foreach my $key (keys %$original_opts) { unless (exists $not_for_completion{$key}) { - $key =~ s/!$//; + my $negatable = ($key =~ s/!$//); if ($key =~ /[:=][si]$/) { $key =~ s/[:=][si]$//; push (@send_email_opts, "--$_=") foreach (split (/\|/, $key)); } else { push (@send_email_opts, "--$_") foreach (split (/\|/, $key)); + if ($negatable) { + push (@send_email_opts, "--no-$_") foreach (split (/\|/, $key)); + } } } } @@ -228,7 +231,7 @@ sub system_or_msg { my @sprintf_args = ($cmd_name ? $cmd_name : $args->[0], $exit_code); if (defined $msg) { # Quiet the 'redundant' warning category, except we - # need to support down to Perl 5.8, so we can't do a + # need to support down to Perl 5.8.1, so we can't do a # "no warnings 'redundant'", since that category was # introduced in perl 5.22, and asking for it will die # on older perls. @@ -491,7 +494,6 @@ my %options = ( "bcc=s" => \@getopt_bcc, "no-bcc" => \$no_bcc, "chain-reply-to!" => \$chain_reply_to, - "no-chain-reply-to" => sub {$chain_reply_to = 0}, "sendmail-cmd=s" => \$sendmail_cmd, "smtp-server=s" => \$smtp_server, "smtp-server-option=s" => \@smtp_server_options, @@ -506,36 +508,27 @@ my %options = ( "smtp-auth=s" => \$smtp_auth, "no-smtp-auth" => sub {$smtp_auth = 'none'}, "annotate!" => \$annotate, - "no-annotate" => sub {$annotate = 0}, "compose" => \$compose, "quiet" => \$quiet, "cc-cmd=s" => \$cc_cmd, "header-cmd=s" => \$header_cmd, "no-header-cmd" => \$no_header_cmd, "suppress-from!" => \$suppress_from, - "no-suppress-from" => sub {$suppress_from = 0}, "suppress-cc=s" => \@suppress_cc, "signed-off-cc|signed-off-by-cc!" => \$signed_off_by_cc, - "no-signed-off-cc|no-signed-off-by-cc" => sub {$signed_off_by_cc = 0}, - "cc-cover|cc-cover!" => \$cover_cc, - "no-cc-cover" => sub {$cover_cc = 0}, - "to-cover|to-cover!" => \$cover_to, - "no-to-cover" => sub {$cover_to = 0}, + "cc-cover!" => \$cover_cc, + "to-cover!" => \$cover_to, "confirm=s" => \$confirm, "dry-run" => \$dry_run, "envelope-sender=s" => \$envelope_sender, "thread!" => \$thread, - "no-thread" => sub {$thread = 0}, "validate!" => \$validate, - "no-validate" => sub {$validate = 0}, "transfer-encoding=s" => \$target_xfer_encoding, "format-patch!" => \$format_patch, - "no-format-patch" => sub {$format_patch = 0}, "8bit-encoding=s" => \$auto_8bit_encoding, "compose-encoding=s" => \$compose_encoding, "force" => \$force, "xmailer!" => \$use_xmailer, - "no-xmailer" => sub {$use_xmailer = 0}, "batch-size=i" => \$batch_size, "relogin-delay=i" => \$relogin_delay, "git-completion-helper" => \$git_completion_helper, diff --git a/git-svn.perl b/git-svn.perl index 4e8878f035..b0d0a50984 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1,7 +1,7 @@ #!/usr/bin/perl # Copyright (C) 2006, Eric Wong <normalperson@yhbt.net> # License: GPL v2 or later -use 5.008; +use 5.008001; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); use strict; use vars qw/ $AUTHOR $VERSION @@ -594,6 +594,7 @@ static struct cmd_struct commands[] = { { "remote-fd", cmd_remote_fd, NO_PARSEOPT }, { "repack", cmd_repack, RUN_SETUP }, { "replace", cmd_replace, RUN_SETUP }, + { "replay", cmd_replay, RUN_SETUP }, { "rerere", cmd_rerere, RUN_SETUP }, { "reset", cmd_reset, RUN_SETUP }, { "restore", cmd_restore, RUN_SETUP | NEED_WORK_TREE }, diff --git a/gitk-git/gitk b/gitk-git/gitk index df3ba2ea99..7a087f123d 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -11956,7 +11956,7 @@ proc formatdate {d} { } # This list of encoding names and aliases is distilled from -# http://www.iana.org/assignments/character-sets. +# https://www.iana.org/assignments/character-sets. # Not all of them are supported by Tcl. set encoding_aliases { { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII @@ -12472,7 +12472,7 @@ if {[tk windowingsystem] eq "aqua"} { catch { # follow the XDG base directory specification by default. See - # http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + # https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if {[info exists env(XDG_CONFIG_HOME)] && $env(XDG_CONFIG_HOME) ne ""} { # XDG_CONFIG_HOME environment variable is set set config_file [file join $env(XDG_CONFIG_HOME) git gitk] diff --git a/gitweb/INSTALL b/gitweb/INSTALL index a58e6b3c44..5bfa4968c4 100644 --- a/gitweb/INSTALL +++ b/gitweb/INSTALL @@ -29,7 +29,7 @@ Requirements ------------ - Core git tools - - Perl 5.8 + - Perl 5.8.1 - Perl modules: CGI, Encode, Fcntl, File::Find, File::Basename. - web server @@ -203,7 +203,7 @@ You can specify the following configuration variables when building GIT: created. [Default: /etc/gitweb.conf] * HIGHLIGHT_BIN Path to the highlight executable to use (must be the one from - http://www.andre-simon.de due to assumptions about parameters and output). + http://andre-simon.de/zip/download.php due to assumptions about parameters and output). Useful if highlight is not installed on your webserver's PATH. [Default: highlight] diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index e66eb3d9ba..ccd14e0e30 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -7,7 +7,7 @@ # # This program is licensed under the GPLv2 -use 5.008; +use 5.008001; use strict; use warnings; # handle ACL in file access tests @@ -122,9 +122,9 @@ our $favicon = "++GITWEB_FAVICON++"; our $javascript = "++GITWEB_JS++"; # URI and label (title) of GIT logo link -#our $logo_url = "http://www.kernel.org/pub/software/scm/git/docs/"; +#our $logo_url = "https://www.kernel.org/pub/software/scm/git/docs/"; #our $logo_label = "git documentation"; -our $logo_url = "http://git-scm.com/"; +our $logo_url = "https://git-scm.com/"; our $logo_label = "git homepage"; # source of projects list @@ -197,7 +197,7 @@ our @diff_opts = ('-M'); # taken from git_commit our $prevent_xss = 0; # Path to the highlight executable to use (must be the one from -# http://www.andre-simon.de due to assumptions about parameters and output). +# http://andre-simon.de/zip/download.php due to assumptions about parameters and output). # Useful if highlight is not installed on your webserver's PATH. # [Default: highlight] our $highlight_bin = "++HIGHLIGHT_BIN++"; @@ -269,7 +269,7 @@ our %avatar_size = ( # Leave it undefined (or set to 'undef') to turn off load checking. our $maxload = 300; -# configuration for 'highlight' (http://www.andre-simon.de/) +# configuration for 'highlight' (http://andre-simon.de/doku/highlight/en/highlight.php) # match by basename our %highlight_basename = ( #'Program' => 'py', @@ -728,9 +728,11 @@ our $per_request_config = 1; sub read_config_file { my $filename = shift; return unless defined $filename; - # die if there are errors parsing config file if (-e $filename) { do $filename; + # die if there is a problem accessing the file + die $! if $!; + # die if there are errors parsing config file die $@ if $@; return 1; } @@ -8193,7 +8195,7 @@ sub git_feed { my $have_blame = gitweb_check_feature('blame'); # Atom: http://www.atomenabled.org/developers/syndication/ - # RSS: http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ + # RSS: https://web.archive.org/web/20030729001534/http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ if ($format ne 'rss' && $format ne 'atom') { die_error(400, "Unknown web feed format"); } diff --git a/gitweb/static/gitweb.css b/gitweb/static/gitweb.css index 3212601032..48d2e51015 100644 --- a/gitweb/static/gitweb.css +++ b/gitweb/static/gitweb.css @@ -667,7 +667,7 @@ div.remote { } -/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */ +/* Style definition generated by highlight 2.4.5, http://andre-simon.de/doku/highlight/en/highlight.php */ /* Highlighting theme definition: */ diff --git a/gitweb/static/js/lib/common-lib.js b/gitweb/static/js/lib/common-lib.js index 018bbb7d4c..99e3eb8c3d 100644 --- a/gitweb/static/js/lib/common-lib.js +++ b/gitweb/static/js/lib/common-lib.js @@ -123,8 +123,8 @@ function addCssRule(selector, style) { * NOTE that there are limits and differences compared to native * getElementsByClassName as defined by e.g.: * https://developer.mozilla.org/en/DOM/document.getElementsByClassName - * http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-getelementsbyclassname - * http://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-document-getelementsbyclassname + * https://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-getelementsbyclassname + * https://www.whatwg.org/specs/web-apps/current-work/multipage/dom.html#dom-document-getelementsbyclassname * * Namely, this implementation supports only single class name as * argument and not set of space-separated tokens representing classes, @@ -133,11 +133,11 @@ function addCssRule(selector, style) { * (via getElementsByTagName). * * Based on - * http://code.google.com/p/getelementsbyclassname/ + * https://code.google.com/p/getelementsbyclassname/ * http://www.dustindiaz.com/getelementsbyclass/ - * http://stackoverflow.com/questions/1818865/do-we-have-getelementsbyclassname-in-javascript + * https://stackoverflow.com/questions/1818865/do-we-have-getelementsbyclassname-in-javascript * - * See also http://ejohn.org/blog/getelementsbyclassname-speed-comparison/ + * See also https://johnresig.com/blog/getelementsbyclassname-speed-comparison/ * * @param {String} class: name of _single_ class to find * @param {String} [taghint] limit search to given tags diff --git a/gpg-interface.c b/gpg-interface.c index 48f43c5a21..95e764acb1 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -12,7 +12,6 @@ #include "sigchain.h" #include "tempfile.h" #include "alias.h" -#include "environment.h" static int git_gpg_config(const char *, const char *, const struct config_context *, void *); @@ -762,23 +761,14 @@ static int git_gpg_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "gpg.ssh.defaultkeycommand")) { - if (!value) - return config_error_nonbool(var); + if (!strcmp(var, "gpg.ssh.defaultkeycommand")) return git_config_string(&ssh_default_key_command, var, value); - } - if (!strcmp(var, "gpg.ssh.allowedsignersfile")) { - if (!value) - return config_error_nonbool(var); + if (!strcmp(var, "gpg.ssh.allowedsignersfile")) return git_config_pathname(&ssh_allowed_signers, var, value); - } - if (!strcmp(var, "gpg.ssh.revocationfile")) { - if (!value) - return config_error_nonbool(var); + if (!strcmp(var, "gpg.ssh.revocationfile")) return git_config_pathname(&ssh_revocation_file, var, value); - } if (!strcmp(var, "gpg.program") || !strcmp(var, "gpg.openpgp.program")) fmtname = "openpgp"; @@ -1088,7 +1078,7 @@ static int sign_buffer_ssh(struct strbuf *buffer, struct strbuf *signature, if (strstr(signer_stderr.buf, "usage:")) error(_("ssh-keygen -Y sign is needed for ssh signing (available in openssh version 8.2p1+)")); - error("%s", signer_stderr.buf); + ret = error("%s", signer_stderr.buf); goto out; } diff --git a/gpg-interface.h b/gpg-interface.h index 143cdc1c02..7cd98161f7 100644 --- a/gpg-interface.h +++ b/gpg-interface.h @@ -66,7 +66,7 @@ size_t parse_signed_buffer(const char *buf, size_t size); * Create a detached signature for the contents of "buffer" and append * it after "signature"; "buffer" and "signature" can be the same * strbuf instance, which would cause the detached signature appended - * at the end. + * at the end. Returns 0 on success, non-zero on failure. */ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key); @@ -130,7 +130,7 @@ void graph_setup_line_prefix(struct diff_options *diffopt); * This functions must be called BEFORE graph_init() is called. * * NOTE: This function isn't used in Git outside graph.c but it is used - * by CGit (http://git.zx2c4.com/cgit/) to use HTML for colors. + * by CGit (https://git.zx2c4.com/cgit/) to use HTML for colors. */ void graph_set_column_colors(const char **colors, unsigned short colors_max); @@ -196,7 +196,7 @@ int graph_is_commit_finished(struct git_graph const *graph); * graph_update() is called. * * NOTE: This function isn't used in Git outside graph.c but it is used - * by CGit (http://git.zx2c4.com/cgit/) to wrap HTML around graph lines. + * by CGit (https://git.zx2c4.com/cgit/) to wrap HTML around graph lines. */ int graph_next_line(struct git_graph *graph, struct strbuf *sb); @@ -9,7 +9,6 @@ #include "xdiff-interface.h" #include "diff.h" #include "diffcore.h" -#include "commit.h" #include "quote.h" #include "help.h" @@ -464,8 +464,11 @@ static int get_alias(const char *var, const char *value, { struct string_list *list = data; - if (skip_prefix(var, "alias.", &var)) + if (skip_prefix(var, "alias.", &var)) { + if (!value) + return config_error_nonbool(var); string_list_append(list, var)->util = xstrdup(value); + } return 0; } diff --git a/http-backend.c b/http-backend.c index ff07b87e64..1ed1e29d07 100644 --- a/http-backend.c +++ b/http-backend.c @@ -38,6 +38,7 @@ struct rpc_service { static struct rpc_service rpc_service[] = { { "upload-pack", "uploadpack", 1, 1 }, { "receive-pack", "receivepack", 0, -1 }, + { "upload-archive", "uploadarchive", 0, -1 }, }; static struct string_list *get_parameters(void) @@ -639,10 +640,15 @@ static void check_content_type(struct strbuf *hdr, const char *accepted_type) static void service_rpc(struct strbuf *hdr, char *service_name) { - const char *argv[] = {NULL, "--stateless-rpc", ".", NULL}; + struct strvec argv = STRVEC_INIT; struct rpc_service *svc = select_service(hdr, service_name); struct strbuf buf = STRBUF_INIT; + strvec_push(&argv, svc->name); + if (strcmp(service_name, "git-upload-archive")) + strvec_push(&argv, "--stateless-rpc"); + strvec_push(&argv, "."); + strbuf_reset(&buf); strbuf_addf(&buf, "application/x-git-%s-request", svc->name); check_content_type(hdr, buf.buf); @@ -655,9 +661,9 @@ static void service_rpc(struct strbuf *hdr, char *service_name) end_headers(hdr); - argv[0] = svc->name; - run_service(argv, svc->buffer_input); + run_service(argv.v, svc->buffer_input); strbuf_release(&buf); + strvec_clear(&argv); } static int dead; @@ -723,6 +729,7 @@ static struct service_cmd { {"GET", "/objects/pack/pack-[0-9a-f]{64}\\.idx$", get_idx_file}, {"POST", "/git-upload-pack$", service_rpc}, + {"POST", "/git-upload-archive$", service_rpc}, {"POST", "/git-receive-pack$", service_rpc} }; diff --git a/http-fetch.c b/http-fetch.c index fffda59267..bec94988bb 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -1,12 +1,12 @@ #include "git-compat-util.h" #include "config.h" -#include "exec-cmd.h" #include "gettext.h" #include "hex.h" #include "http.h" #include "walker.h" #include "setup.h" #include "strvec.h" +#include "url.h" #include "urlmatch.h" #include "trace2.h" diff --git a/http-push.c b/http-push.c index a704f490fd..12d1113741 100644 --- a/http-push.c +++ b/http-push.c @@ -6,10 +6,8 @@ #include "tag.h" #include "blob.h" #include "http.h" -#include "refs.h" #include "diff.h" #include "revision.h" -#include "exec-cmd.h" #include "remote.h" #include "list-objects.h" #include "setup.h" @@ -17,6 +15,7 @@ #include "strvec.h" #include "tree.h" #include "tree-walk.h" +#include "url.h" #include "packfile.h" #include "object-store-ll.h" #include "commit-reach.h" @@ -1852,6 +1851,7 @@ int cmd_main(int argc, const char **argv) if (oideq(&ref->old_oid, &ref->peer_ref->new_oid)) { if (push_verbosely) + /* stable plumbing output; do not modify or localize */ fprintf(stderr, "'%s': up-to-date\n", ref->name); if (helper_status) printf("ok %s up to date\n", ref->name); @@ -1872,6 +1872,7 @@ int cmd_main(int argc, const char **argv) * commits at the remote end and likely * we were not up to date to begin with. */ + /* stable plumbing output; do not modify or localize */ error("remote '%s' is not an ancestor of\n" "local '%s'.\n" "Maybe you are not up-to-date and " diff --git a/http-walker.c b/http-walker.c index 78d99f7c4b..b395ef1327 100644 --- a/http-walker.c +++ b/http-walker.c @@ -1,6 +1,5 @@ #include "git-compat-util.h" #include "repository.h" -#include "commit.h" #include "hex.h" #include "walker.h" #include "http.h" @@ -4,7 +4,6 @@ #include "http.h" #include "config.h" #include "pack.h" -#include "sideband.h" #include "run-command.h" #include "url.h" #include "urlmatch.h" @@ -15,7 +14,6 @@ #include "trace.h" #include "transport.h" #include "packfile.h" -#include "protocol.h" #include "string-list.h" #include "object-file.h" #include "object-store-ll.h" @@ -1902,7 +1900,7 @@ static void write_accept_language(struct strbuf *buf) * MAX_DECIMAL_PLACES must not be larger than 3. If it is larger than * that, q-value will be smaller than 0.001, the minimum q-value the * HTTP specification allows. See - * http://tools.ietf.org/html/rfc7231#section-5.3.1 for q-value. + * https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.1 for q-value. */ const int MAX_DECIMAL_PLACES = 3; const int MAX_LANGUAGE_TAGS = 1000; @@ -10,7 +10,6 @@ struct packed_git; #include "strbuf.h" #include "remote.h" -#include "url.h" #define DEFAULT_MAX_REQUESTS 5 diff --git a/imap-send.c b/imap-send.c index 996651e4f8..f2e1947e63 100644 --- a/imap-send.c +++ b/imap-send.c @@ -18,13 +18,12 @@ * 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/>. + * along with this program; if not, see <https://www.gnu.org/licenses/>. */ #include "git-compat-util.h" #include "config.h" #include "credential.h" -#include "exec-cmd.h" #include "gettext.h" #include "run-command.h" #include "parse-options.h" @@ -860,7 +859,7 @@ static void imap_close_store(struct imap_store *ctx) /* * hexchar() and cram() functions are based on the code from the isync - * project (http://isync.sf.net/). + * project (https://isync.sourceforge.io/). */ static char hexchar(unsigned int b) { @@ -1346,7 +1345,7 @@ static int git_imap_config(const char *var, const char *val, server.port = git_config_int(var, val, ctx->kvi); else if (!strcmp("imap.host", var)) { if (!val) { - git_die_config("imap.host", "Missing value for 'imap.host'"); + return config_error_nonbool(var); } else { if (starts_with(val, "imap:")) val += 5; diff --git a/json-writer.h b/json-writer.h index 209355e0f1..04413bd1af 100644 --- a/json-writer.h +++ b/json-writer.h @@ -3,8 +3,8 @@ /* * JSON data structures are defined at: - * [1] http://www.ietf.org/rfc/rfc7159.txt - * [2] http://json.org/ + * [1] https://www.ietf.org/rfc/rfc7159.txt + * [2] https://www.json.org/ * * The JSON-writer API allows one to build JSON data structures using a * simple wrapper around a "struct strbuf" buffer. It is intended as a @@ -18,7 +18,7 @@ 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/>. */ + along with this program; if not, see <https://www.gnu.org/licenses/>. */ /* Written August 1989 by Mike Haertel. The author may be reached (Email) at the address mike@ai.mit.edu, @@ -20,7 +20,7 @@ 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/>. */ + along with this program; if not, see <https://www.gnu.org/licenses/>. */ /* Written August 1989 by Mike Haertel. The author may be reached (Email) at the address mike@ai.mit.edu, diff --git a/line-log.c b/line-log.c index 24a1ecb677..8ff6ccb772 100644 --- a/line-log.c +++ b/line-log.c @@ -1,8 +1,8 @@ #include "git-compat-util.h" +#include "diffcore.h" #include "line-range.h" #include "hex.h" #include "tag.h" -#include "blob.h" #include "tree.h" #include "diff.h" #include "commit.h" @@ -12,8 +12,6 @@ #include "xdiff-interface.h" #include "strbuf.h" #include "log-tree.h" -#include "graph.h" -#include "userdiff.h" #include "line-log.h" #include "setup.h" #include "strvec.h" diff --git a/line-log.h b/line-log.h index 4291da8d79..e9dadbc1a5 100644 --- a/line-log.h +++ b/line-log.h @@ -1,8 +1,6 @@ #ifndef LINE_LOG_H #define LINE_LOG_H -#include "diffcore.h" - struct rev_info; struct commit; struct string_list; diff --git a/line-range.c b/line-range.c index 47bf0d6f1a..60f0e5ada8 100644 --- a/line-range.c +++ b/line-range.c @@ -1,7 +1,6 @@ #include "git-compat-util.h" #include "line-range.h" #include "xdiff-interface.h" -#include "strbuf.h" #include "userdiff.h" /* diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index 8a08b7af49..c5f363ca6f 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -1,11 +1,6 @@ #include "git-compat-util.h" -#include "commit.h" #include "config.h" #include "gettext.h" -#include "revision.h" -#include "strvec.h" -#include "list-objects.h" -#include "list-objects-filter.h" #include "list-objects-filter-options.h" #include "promisor-remote.h" #include "trace.h" diff --git a/list-objects-filter.c b/list-objects-filter.c index 9327ccd505..da287cc8e0 100644 --- a/list-objects-filter.c +++ b/list-objects-filter.c @@ -2,14 +2,9 @@ #include "dir.h" #include "gettext.h" #include "hex.h" -#include "tag.h" #include "commit.h" -#include "tree.h" -#include "blob.h" #include "diff.h" -#include "tree-walk.h" #include "revision.h" -#include "list-objects.h" #include "list-objects-filter.h" #include "list-objects-filter-options.h" #include "oidmap.h" @@ -19,7 +19,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see - * <http://www.gnu.org/licenses/>. + * <https://www.gnu.org/licenses/>. */ #ifndef LIST_H diff --git a/log-tree.c b/log-tree.c index 504da6b519..337b9334cd 100644 --- a/log-tree.c +++ b/log-tree.c @@ -2,6 +2,7 @@ #include "commit-reach.h" #include "config.h" #include "diff.h" +#include "diffcore.h" #include "environment.h" #include "hex.h" #include "object-name.h" @@ -5,7 +5,6 @@ #include "hex.h" #include "repository.h" #include "refs.h" -#include "remote.h" #include "strvec.h" #include "ls-refs.h" #include "pkt-line.h" diff --git a/mailinfo.c b/mailinfo.c index a07d2da16d..94b9b0abf2 100644 --- a/mailinfo.c +++ b/mailinfo.c @@ -58,12 +58,13 @@ static void parse_bogus_from(struct mailinfo *mi, const struct strbuf *line) static const char *unquote_comment(struct strbuf *outbuf, const char *in) { - int c; int take_next_literally = 0; + int depth = 1; strbuf_addch(outbuf, '('); - while ((c = *in++) != 0) { + while (*in) { + int c = *in++; if (take_next_literally == 1) { take_next_literally = 0; } else { @@ -72,11 +73,14 @@ static const char *unquote_comment(struct strbuf *outbuf, const char *in) take_next_literally = 1; continue; case '(': - in = unquote_comment(outbuf, in); + strbuf_addch(outbuf, '('); + depth++; continue; case ')': strbuf_addch(outbuf, ')'); - return in; + if (!--depth) + return in; + continue; } } @@ -88,10 +92,10 @@ static const char *unquote_comment(struct strbuf *outbuf, const char *in) static const char *unquote_quoted_string(struct strbuf *outbuf, const char *in) { - int c; int take_next_literally = 0; - while ((c = *in++) != 0) { + while (*in) { + int c = *in++; if (take_next_literally == 1) { take_next_literally = 0; } else { @@ -1253,6 +1257,8 @@ static int git_mailinfo_config(const char *var, const char *value, return 0; } if (!strcmp(var, "mailinfo.quotedcr")) { + if (!value) + return config_error_nonbool(var); if (mailinfo_parse_quoted_cr_action(value, &mi->quoted_cr) != 0) return error(_("bad action '%s' for '%s'"), value, var); return 0; diff --git a/mem-pool.c b/mem-pool.c index c34846d176..2078c22b09 100644 --- a/mem-pool.c +++ b/mem-pool.c @@ -89,9 +89,7 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len) struct mp_block *p = NULL; void *r; - /* round up to a 'GIT_MAX_ALIGNMENT' alignment */ - if (len & (GIT_MAX_ALIGNMENT - 1)) - len += GIT_MAX_ALIGNMENT - (len & (GIT_MAX_ALIGNMENT - 1)); + len = DIV_ROUND_UP(len, GIT_MAX_ALIGNMENT) * GIT_MAX_ALIGNMENT; if (pool->mp_block && pool->mp_block->end - pool->mp_block->next_free >= len) @@ -99,9 +97,9 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len) if (!p) { if (len >= (pool->block_alloc / 2)) - return mem_pool_alloc_block(pool, len, pool->mp_block); - - p = mem_pool_alloc_block(pool, pool->block_alloc, NULL); + p = mem_pool_alloc_block(pool, len, pool->mp_block); + else + p = mem_pool_alloc_block(pool, pool->block_alloc, NULL); } r = p->next_free; @@ -109,6 +107,45 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len) return r; } +static char *mem_pool_strvfmt(struct mem_pool *pool, const char *fmt, + va_list ap) +{ + struct mp_block *block = pool->mp_block; + char *next_free = block ? block->next_free : NULL; + size_t available = block ? block->end - block->next_free : 0; + va_list cp; + int len, len2; + char *ret; + + va_copy(cp, ap); + len = vsnprintf(next_free, available, fmt, cp); + va_end(cp); + if (len < 0) + BUG("your vsnprintf is broken (returned %d)", len); + + ret = mem_pool_alloc(pool, len + 1); /* 1 for NUL */ + + /* Shortcut; relies on mem_pool_alloc() not touching buffer contents. */ + if (ret == next_free) + return ret; + + len2 = vsnprintf(ret, len + 1, fmt, ap); + if (len2 != len) + BUG("your vsnprintf is broken (returns inconsistent lengths)"); + return ret; +} + +char *mem_pool_strfmt(struct mem_pool *pool, const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = mem_pool_strvfmt(pool, fmt, ap); + va_end(ap); + return ret; +} + void *mem_pool_calloc(struct mem_pool *pool, size_t count, size_t size) { size_t len = st_mult(count, size); diff --git a/mem-pool.h b/mem-pool.h index fe7507f022..d1c66413ec 100644 --- a/mem-pool.h +++ b/mem-pool.h @@ -48,6 +48,11 @@ char *mem_pool_strdup(struct mem_pool *pool, const char *str); char *mem_pool_strndup(struct mem_pool *pool, const char *str, size_t len); /* + * Allocate memory from the memory pool and format a string into it. + */ +char *mem_pool_strfmt(struct mem_pool *pool, const char *fmt, ...); + +/* * Move the memory associated with the 'src' pool to the 'dst' pool. The 'src' * pool will be empty and not contain any memory. It still needs to be free'd * with a call to `mem_pool_discard`. diff --git a/merge-blobs.c b/merge-blobs.c index 9293cbf75c..2f659fd014 100644 --- a/merge-blobs.c +++ b/merge-blobs.c @@ -1,6 +1,4 @@ #include "git-compat-util.h" -#include "run-command.h" -#include "xdiff-interface.h" #include "merge-ll.h" #include "blob.h" #include "merge-blobs.h" diff --git a/merge-ll.c b/merge-ll.c index 8fcf2d3710..61e0ae5398 100644 --- a/merge-ll.c +++ b/merge-ll.c @@ -185,9 +185,9 @@ static void create_temp(mmfile_t *src, char *path, size_t len) static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn, mmbuffer_t *result, const char *path, - mmfile_t *orig, const char *orig_name UNUSED, - mmfile_t *src1, const char *name1 UNUSED, - mmfile_t *src2, const char *name2 UNUSED, + mmfile_t *orig, const char *orig_name, + mmfile_t *src1, const char *name1, + mmfile_t *src2, const char *name2, const struct ll_merge_options *opts, int marker_size) { @@ -222,6 +222,12 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn, strbuf_addf(&cmd, "%d", marker_size); else if (skip_prefix(format, "P", &format)) sq_quote_buf(&cmd, path); + else if (skip_prefix(format, "S", &format)) + sq_quote_buf(&cmd, orig_name ? orig_name : ""); + else if (skip_prefix(format, "X", &format)) + sq_quote_buf(&cmd, name1 ? name1 : ""); + else if (skip_prefix(format, "Y", &format)) + sq_quote_buf(&cmd, name2 ? name2 : ""); else strbuf_addch(&cmd, '%'); } @@ -286,7 +292,7 @@ static int read_merge_config(const char *var, const char *value, * after seeing merge.<name>.var1. */ for (fn = ll_user_merge; fn; fn = fn->next) - if (!strncmp(fn->name, name, namelen) && !fn->name[namelen]) + if (!xstrncmpz(fn->name, name, namelen)) break; if (!fn) { CALLOC_ARRAY(fn, 1); @@ -301,7 +307,7 @@ static int read_merge_config(const char *var, const char *value, if (!strcmp("driver", key)) { if (!value) - return error("%s: lacks value", var); + return config_error_nonbool(var); /* * merge.<name>.driver specifies the command line: * @@ -315,7 +321,12 @@ static int read_merge_config(const char *var, const char *value, * %B - temporary file name for the other branches' version. * %L - conflict marker length * %P - the original path (safely quoted for the shell) + * %S - the revision for the merge base + * %X - the revision for our version + * %Y - the revision for their version * + * If the file is not named indentically in all versions, then each + * revision is joined with the corresponding path, separated by a colon. * The external merge driver should write the results in the * file named by %A, and signal that it has done with zero exit * status. diff --git a/merge-ort.c b/merge-ort.c index 6491070d96..6a48aea227 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -18,8 +18,8 @@ #include "merge-ort.h" #include "alloc.h" +#include "advice.h" #include "attr.h" -#include "blob.h" #include "cache-tree.h" #include "commit.h" #include "commit-reach.h" @@ -39,11 +39,10 @@ #include "path.h" #include "promisor-remote.h" #include "read-cache-ll.h" +#include "refs.h" #include "revision.h" #include "sparse-index.h" #include "strmap.h" -#include "submodule-config.h" -#include "submodule.h" #include "trace2.h" #include "tree.h" #include "unpack-trees.h" @@ -2644,7 +2643,7 @@ static void apply_directory_rename_modifications(struct merge_options *opt, oidcpy(&ci->stages[i].oid, null_oid()); } - // Now we want to focus on new_ci, so reassign ci to it + /* Now we want to focus on new_ci, so reassign ci to it. */ ci = new_ci; } @@ -4558,7 +4557,7 @@ static void print_submodule_conflict_suggestion(struct string_list *csub) { " - commit the resulting index in the superproject\n"), tmp.buf, subs.buf); - printf("%s", msg.buf); + advise_if_enabled(ADVICE_SUBMODULE_MERGE_CONFLICT, "%s", msg.buf); strbuf_release(&subs); strbuf_release(&tmp); @@ -4662,9 +4661,6 @@ void merge_switch_to_result(struct merge_options *opt, { assert(opt->priv == NULL); if (result->clean >= 0 && update_worktree_and_index) { - const char *filename; - FILE *fp; - trace2_region_enter("merge", "checkout", opt->repo); if (checkout(opt, head, result->tree)) { /* failure to function */ @@ -4690,10 +4686,17 @@ void merge_switch_to_result(struct merge_options *opt, trace2_region_leave("merge", "record_conflicted", opt->repo); trace2_region_enter("merge", "write_auto_merge", opt->repo); - filename = git_path_auto_merge(opt->repo); - fp = xfopen(filename, "w"); - fprintf(fp, "%s\n", oid_to_hex(&result->tree->object.oid)); - fclose(fp); + if (refs_update_ref(get_main_ref_store(opt->repo), "", "AUTO_MERGE", + &result->tree->object.oid, NULL, REF_NO_DEREF, + UPDATE_REFS_MSG_ON_ERR)) { + /* failure to function */ + opt->priv = NULL; + result->clean = -1; + merge_finalize(opt, result); + trace2_region_leave("merge", "write_auto_merge", + opt->repo); + return; + } trace2_region_leave("merge", "write_auto_merge", opt->repo); } if (display_update_msgs) diff --git a/merge-recursive.c b/merge-recursive.c index e3beb0801b..a0c3e7a2d9 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -6,10 +6,7 @@ #include "git-compat-util.h" #include "merge-recursive.h" -#include "advice.h" #include "alloc.h" -#include "attr.h" -#include "blob.h" #include "cache-tree.h" #include "commit.h" #include "commit-reach.h" @@ -32,8 +29,6 @@ #include "revision.h" #include "sparse-index.h" #include "string-list.h" -#include "submodule-config.h" -#include "submodule.h" #include "symlinks.h" #include "tag.h" #include "tree-walk.h" @@ -1,6 +1,4 @@ #include "git-compat-util.h" -#include "diff.h" -#include "diffcore.h" #include "gettext.h" #include "hash.h" #include "hex.h" @@ -13,7 +11,6 @@ #include "tree.h" #include "tree-walk.h" #include "unpack-trees.h" -#include "dir.h" static const char *merge_argument(struct commit *commit) { diff --git a/mergetools/vimdiff b/mergetools/vimdiff index 06937acbf5..97e376329b 100644 --- a/mergetools/vimdiff +++ b/mergetools/vimdiff @@ -371,9 +371,17 @@ diff_cmd_help () { merge_cmd () { - layout=$(git config mergetool.vimdiff.layout) + TOOL=$1 - case "$1" in + layout=$(git config "mergetool.$TOOL.layout") + + # backward compatibility: + if test -z "$layout" + then + layout=$(git config mergetool.vimdiff.layout) + fi + + case "$TOOL" in *vimdiff) if test -z "$layout" then @@ -21,6 +21,7 @@ #include "refs.h" #include "revision.h" #include "list-objects.h" +#include "pack-revindex.h" #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */ #define MIDX_VERSION 1 @@ -33,6 +34,7 @@ #define MIDX_CHUNK_ALIGNMENT 4 #define MIDX_CHUNKID_PACKNAMES 0x504e414d /* "PNAM" */ +#define MIDX_CHUNKID_BITMAPPEDPACKS 0x42544d50 /* "BTMP" */ #define MIDX_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */ #define MIDX_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */ #define MIDX_CHUNKID_OBJECTOFFSETS 0x4f4f4646 /* "OOFF" */ @@ -41,6 +43,7 @@ #define MIDX_CHUNK_FANOUT_SIZE (sizeof(uint32_t) * 256) #define MIDX_CHUNK_OFFSET_WIDTH (2 * sizeof(uint32_t)) #define MIDX_CHUNK_LARGE_OFFSET_WIDTH (sizeof(uint64_t)) +#define MIDX_CHUNK_BITMAPPED_PACKS_WIDTH (2 * sizeof(uint32_t)) #define MIDX_LARGE_OFFSET_NEEDED 0x80000000 #define PACK_EXPIRED UINT_MAX @@ -64,6 +67,7 @@ void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m) static int midx_read_oid_fanout(const unsigned char *chunk_start, size_t chunk_size, void *data) { + int i; struct multi_pack_index *m = data; m->chunk_oid_fanout = (uint32_t *)chunk_start; @@ -71,6 +75,16 @@ static int midx_read_oid_fanout(const unsigned char *chunk_start, error(_("multi-pack-index OID fanout is of the wrong size")); return 1; } + for (i = 0; i < 255; i++) { + uint32_t oid_fanout1 = ntohl(m->chunk_oid_fanout[i]); + uint32_t oid_fanout2 = ntohl(m->chunk_oid_fanout[i+1]); + + if (oid_fanout1 > oid_fanout2) { + error(_("oid fanout out of order: fanout[%d] = %"PRIx32" > %"PRIx32" = fanout[%d]"), + i, oid_fanout1, oid_fanout2, i + 1); + return 1; + } + } m->num_objects = ntohl(m->chunk_oid_fanout[255]); return 0; } @@ -164,6 +178,8 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local m->num_packs = get_be32(m->data + MIDX_BYTE_NUM_PACKS); + m->preferred_pack_idx = -1; + cf = init_chunkfile(NULL); if (read_table_of_contents(cf, m->data, midx_size, @@ -182,6 +198,9 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local pair_chunk(cf, MIDX_CHUNKID_LARGEOFFSETS, &m->chunk_large_offsets, &m->chunk_large_offsets_len); + pair_chunk(cf, MIDX_CHUNKID_BITMAPPEDPACKS, + (const unsigned char **)&m->chunk_bitmapped_packs, + &m->chunk_bitmapped_packs_len); if (git_env_bool("GIT_TEST_MIDX_READ_RIDX", 1)) pair_chunk(cf, MIDX_CHUNKID_REVINDEX, &m->chunk_revindex, @@ -275,6 +294,26 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t return 0; } +int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m, + struct bitmapped_pack *bp, uint32_t pack_int_id) +{ + if (!m->chunk_bitmapped_packs) + return error(_("MIDX does not contain the BTMP chunk")); + + if (prepare_midx_pack(r, m, pack_int_id)) + return error(_("could not load bitmapped pack %"PRIu32), pack_int_id); + + bp->p = m->packs[pack_int_id]; + bp->bitmap_pos = get_be32((char *)m->chunk_bitmapped_packs + + MIDX_CHUNK_BITMAPPED_PACKS_WIDTH * pack_int_id); + bp->bitmap_nr = get_be32((char *)m->chunk_bitmapped_packs + + MIDX_CHUNK_BITMAPPED_PACKS_WIDTH * pack_int_id + + sizeof(uint32_t)); + bp->pack_int_id = pack_int_id; + + return 0; +} + int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result) { return bsearch_hash(oid->hash, m->chunk_oid_fanout, m->chunk_oid_lookup, @@ -392,7 +431,8 @@ static int cmp_idx_or_pack_name(const char *idx_or_pack_name, return strcmp(idx_or_pack_name, idx_name); } -int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name) +int midx_locate_pack(struct multi_pack_index *m, const char *idx_or_pack_name, + uint32_t *pos) { uint32_t first = 0, last = m->num_packs; @@ -403,8 +443,11 @@ int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name) current = m->pack_names[mid]; cmp = cmp_idx_or_pack_name(idx_or_pack_name, current); - if (!cmp) + if (!cmp) { + if (pos) + *pos = mid; return 1; + } if (cmp > 0) { first = mid + 1; continue; @@ -415,6 +458,28 @@ int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name) return 0; } +int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name) +{ + return midx_locate_pack(m, idx_or_pack_name, NULL); +} + +int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id) +{ + if (m->preferred_pack_idx == -1) { + if (load_midx_revindex(m) < 0) { + m->preferred_pack_idx = -2; + return -1; + } + + m->preferred_pack_idx = + nth_midxed_pack_int_id(m, pack_pos_to_midx(m, 0)); + } else if (m->preferred_pack_idx == -2) + return -1; /* no revindex */ + + *pack_int_id = m->preferred_pack_idx; + return 0; +} + int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local) { struct multi_pack_index *m; @@ -457,13 +522,31 @@ static size_t write_midx_header(struct hashfile *f, return MIDX_HEADER_SIZE; } +#define BITMAP_POS_UNKNOWN (~((uint32_t)0)) + struct pack_info { uint32_t orig_pack_int_id; char *pack_name; struct packed_git *p; + + uint32_t bitmap_pos; + uint32_t bitmap_nr; + unsigned expired : 1; }; +static void fill_pack_info(struct pack_info *info, + struct packed_git *p, const char *pack_name, + uint32_t orig_pack_int_id) +{ + memset(info, 0, sizeof(struct pack_info)); + + info->orig_pack_int_id = orig_pack_int_id; + info->pack_name = xstrdup(pack_name); + info->p = p; + info->bitmap_pos = BITMAP_POS_UNKNOWN; +} + static int pack_info_compare(const void *_a, const void *_b) { struct pack_info *a = (struct pack_info *)_a; @@ -504,6 +587,7 @@ static void add_pack_to_midx(const char *full_path, size_t full_path_len, const char *file_name, void *data) { struct write_midx_context *ctx = data; + struct packed_git *p; if (ends_with(file_name, ".idx")) { display_progress(ctx->progress, ++ctx->pack_paths_checked); @@ -530,27 +614,22 @@ static void add_pack_to_midx(const char *full_path, size_t full_path_len, ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc); - ctx->info[ctx->nr].p = add_packed_git(full_path, - full_path_len, - 0); - - if (!ctx->info[ctx->nr].p) { + p = add_packed_git(full_path, full_path_len, 0); + if (!p) { warning(_("failed to add packfile '%s'"), full_path); return; } - if (open_pack_index(ctx->info[ctx->nr].p)) { + if (open_pack_index(p)) { warning(_("failed to open pack-index '%s'"), full_path); - close_pack(ctx->info[ctx->nr].p); - FREE_AND_NULL(ctx->info[ctx->nr].p); + close_pack(p); + free(p); return; } - ctx->info[ctx->nr].pack_name = xstrdup(file_name); - ctx->info[ctx->nr].orig_pack_int_id = ctx->nr; - ctx->info[ctx->nr].expired = 0; + fill_pack_info(&ctx->info[ctx->nr], p, file_name, ctx->nr); ctx->nr++; } } @@ -806,6 +885,26 @@ static int write_midx_pack_names(struct hashfile *f, void *data) return 0; } +static int write_midx_bitmapped_packs(struct hashfile *f, void *data) +{ + struct write_midx_context *ctx = data; + size_t i; + + for (i = 0; i < ctx->nr; i++) { + struct pack_info *pack = &ctx->info[i]; + if (pack->expired) + continue; + + if (pack->bitmap_pos == BITMAP_POS_UNKNOWN && pack->bitmap_nr) + BUG("pack '%s' has no bitmap position, but has %d bitmapped object(s)", + pack->pack_name, pack->bitmap_nr); + + hashwrite_be32(f, pack->bitmap_pos); + hashwrite_be32(f, pack->bitmap_nr); + } + return 0; +} + static int write_midx_oid_fanout(struct hashfile *f, void *data) { @@ -973,8 +1072,19 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx) QSORT(data, ctx->entries_nr, midx_pack_order_cmp); ALLOC_ARRAY(pack_order, ctx->entries_nr); - for (i = 0; i < ctx->entries_nr; i++) + for (i = 0; i < ctx->entries_nr; i++) { + struct pack_midx_entry *e = &ctx->entries[data[i].nr]; + struct pack_info *pack = &ctx->info[ctx->pack_perm[e->pack_int_id]]; + if (pack->bitmap_pos == BITMAP_POS_UNKNOWN) + pack->bitmap_pos = i; + pack->bitmap_nr++; pack_order[i] = data[i].nr; + } + for (i = 0; i < ctx->nr; i++) { + struct pack_info *pack = &ctx->info[ctx->pack_perm[i]]; + if (pack->bitmap_pos == BITMAP_POS_UNKNOWN) + pack->bitmap_pos = 0; + } free(data); trace2_region_leave("midx", "midx_pack_order", the_repository); @@ -1275,6 +1385,7 @@ static int write_midx_internal(const char *object_dir, struct hashfile *f = NULL; struct lock_file lk; struct write_midx_context ctx = { 0 }; + int bitmapped_packs_concat_len = 0; int pack_name_concat_len = 0; int dropped_packs = 0; int result = 0; @@ -1310,11 +1421,6 @@ static int write_midx_internal(const char *object_dir, for (i = 0; i < ctx.m->num_packs; i++) { ALLOC_GROW(ctx.info, ctx.nr + 1, ctx.alloc); - ctx.info[ctx.nr].orig_pack_int_id = i; - ctx.info[ctx.nr].pack_name = xstrdup(ctx.m->pack_names[i]); - ctx.info[ctx.nr].p = ctx.m->packs[i]; - ctx.info[ctx.nr].expired = 0; - if (flags & MIDX_WRITE_REV_INDEX) { /* * If generating a reverse index, need to have @@ -1330,10 +1436,10 @@ static int write_midx_internal(const char *object_dir, if (open_pack_index(ctx.m->packs[i])) die(_("could not open index for %s"), ctx.m->packs[i]->pack_name); - ctx.info[ctx.nr].p = ctx.m->packs[i]; } - ctx.nr++; + fill_pack_info(&ctx.info[ctx.nr++], ctx.m->packs[i], + ctx.m->pack_names[i], i); } } @@ -1492,8 +1598,10 @@ static int write_midx_internal(const char *object_dir, } for (i = 0; i < ctx.nr; i++) { - if (!ctx.info[i].expired) - pack_name_concat_len += strlen(ctx.info[i].pack_name) + 1; + if (ctx.info[i].expired) + continue; + pack_name_concat_len += strlen(ctx.info[i].pack_name) + 1; + bitmapped_packs_concat_len += 2 * sizeof(uint32_t); } /* Check that the preferred pack wasn't expired (if given). */ @@ -1553,6 +1661,9 @@ static int write_midx_internal(const char *object_dir, add_chunk(cf, MIDX_CHUNKID_REVINDEX, st_mult(ctx.entries_nr, sizeof(uint32_t)), write_midx_revindex); + add_chunk(cf, MIDX_CHUNKID_BITMAPPEDPACKS, + bitmapped_packs_concat_len, + write_midx_bitmapped_packs); } write_midx_header(f, get_num_chunks(cf), ctx.nr - dropped_packs); @@ -1592,8 +1703,13 @@ static int write_midx_internal(const char *object_dir, flags) < 0) { error(_("could not write multi-pack bitmap")); result = 1; + clear_packing_data(&pdata); + free(commits); goto cleanup; } + + clear_packing_data(&pdata); + free(commits); } /* * NOTE: Do not use ctx.entries beyond this point, since it might @@ -1782,15 +1898,6 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag } stop_progress(&progress); - for (i = 0; i < 255; i++) { - uint32_t oid_fanout1 = ntohl(m->chunk_oid_fanout[i]); - uint32_t oid_fanout2 = ntohl(m->chunk_oid_fanout[i + 1]); - - if (oid_fanout1 > oid_fanout2) - midx_report(_("oid fanout out of order: fanout[%d] = %"PRIx32" > %"PRIx32" = fanout[%d]"), - i, oid_fanout1, oid_fanout2, i + 1); - } - if (m->num_objects == 0) { midx_report(_("the midx contains no oid")); /* @@ -1,12 +1,12 @@ #ifndef MIDX_H #define MIDX_H -#include "repository.h" #include "string-list.h" struct object_id; struct pack_entry; struct repository; +struct bitmapped_pack; #define GIT_TEST_MULTI_PACK_INDEX "GIT_TEST_MULTI_PACK_INDEX" #define GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP \ @@ -28,11 +28,14 @@ struct multi_pack_index { unsigned char num_chunks; uint32_t num_packs; uint32_t num_objects; + int preferred_pack_idx; int local; const unsigned char *chunk_pack_names; size_t chunk_pack_names_len; + const uint32_t *chunk_bitmapped_packs; + size_t chunk_bitmapped_packs_len; const uint32_t *chunk_oid_fanout; const unsigned char *chunk_oid_lookup; const unsigned char *chunk_object_offsets; @@ -58,6 +61,8 @@ void get_midx_rev_filename(struct strbuf *out, struct multi_pack_index *m); struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local); int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id); +int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m, + struct bitmapped_pack *bp, uint32_t pack_int_id); int bsearch_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result); off_t nth_midxed_offset(struct multi_pack_index *m, uint32_t pos); uint32_t nth_midxed_pack_int_id(struct multi_pack_index *m, uint32_t pos); @@ -65,7 +70,11 @@ struct object_id *nth_midxed_object_oid(struct object_id *oid, struct multi_pack_index *m, uint32_t n); int fill_midx_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e, struct multi_pack_index *m); -int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name); +int midx_contains_pack(struct multi_pack_index *m, + const char *idx_or_pack_name); +int midx_locate_pack(struct multi_pack_index *m, const char *idx_or_pack_name, + uint32_t *pos); +int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id); int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local); /* diff --git a/negotiator/noop.c b/negotiator/noop.c index de39028ab7..65e3c20008 100644 --- a/negotiator/noop.c +++ b/negotiator/noop.c @@ -1,6 +1,5 @@ #include "git-compat-util.h" #include "noop.h" -#include "../commit.h" #include "../fetch-negotiator.h" static void known_common(struct fetch_negotiator *n UNUSED, diff --git a/notes-utils.c b/notes-utils.c index 97c031c26e..6197a5a455 100644 --- a/notes-utils.c +++ b/notes-utils.c @@ -5,7 +5,6 @@ #include "gettext.h" #include "refs.h" #include "notes-utils.h" -#include "repository.h" #include "strbuf.h" void create_notes_commit(struct repository *r, @@ -112,6 +111,8 @@ static int notes_rewrite_config(const char *k, const char *v, } return 0; } else if (!c->refs_from_env && !strcmp(k, "notes.rewriteref")) { + if (!v) + return config_error_nonbool(k); /* note that a refs/ prefix is implied in the * underlying for_each_glob_ref */ if (starts_with(v, "refs/notes/")) @@ -5,8 +5,6 @@ #include "notes.h" #include "object-name.h" #include "object-store-ll.h" -#include "blob.h" -#include "tree.h" #include "utf8.h" #include "strbuf.h" #include "tree-walk.h" diff --git a/object-file.c b/object-file.c index 7c7afe5793..619f039ebc 100644 --- a/object-file.c +++ b/object-file.c @@ -15,24 +15,16 @@ #include "hex.h" #include "string-list.h" #include "lockfile.h" -#include "delta.h" #include "pack.h" -#include "blob.h" #include "commit.h" #include "run-command.h" -#include "tag.h" -#include "tree.h" -#include "tree-walk.h" #include "refs.h" -#include "pack-revindex.h" -#include "hash-lookup.h" #include "bulk-checkin.h" #include "repository.h" #include "replace-object.h" #include "streaming.h" #include "dir.h" #include "list.h" -#include "mergesort.h" #include "quote.h" #include "packfile.h" #include "object-file.h" diff --git a/object-name.c b/object-name.c index 0bfa29dbbf..511f09bc0f 100644 --- a/object-name.c +++ b/object-name.c @@ -8,7 +8,6 @@ #include "tag.h" #include "commit.h" #include "tree.h" -#include "blob.h" #include "tree-walk.h" #include "refs.h" #include "remote.h" @@ -21,7 +20,6 @@ #include "read-cache-ll.h" #include "repository.h" #include "setup.h" -#include "submodule.h" #include "midx.h" #include "commit-reach.h" #include "date.h" @@ -1036,6 +1034,15 @@ static int get_oid_basic(struct repository *r, const char *str, int len, len, str, show_date(co_time, co_tz, DATE_MODE(RFC2822))); } + } else if (nth == co_cnt && !is_null_oid(oid)) { + /* + * We were asked for the Nth reflog (counting + * from 0), but there were only N entries. + * read_ref_at() will have returned "1" to tell + * us it did not find an entry, but it did + * still fill in the oid with the "old" value, + * which we can use. + */ } else { if (flags & GET_OID_QUIETLY) { exit(128); @@ -47,8 +47,7 @@ int type_from_string_gently(const char *str, ssize_t len, int gentle) len = strlen(str); for (i = 1; i < ARRAY_SIZE(object_type_strings); i++) - if (!strncmp(str, object_type_strings[i], len) && - object_type_strings[i][len] == '\0') + if (!xstrncmpz(object_type_strings[i], str, len)) return i; if (gentle) diff --git a/oss-fuzz/.gitignore b/oss-fuzz/.gitignore index 9acb74412e..5b95408825 100644 --- a/oss-fuzz/.gitignore +++ b/oss-fuzz/.gitignore @@ -1,3 +1,4 @@ fuzz-commit-graph +fuzz-date fuzz-pack-headers fuzz-pack-idx diff --git a/oss-fuzz/dummy-cmd-main.c b/oss-fuzz/dummy-cmd-main.c new file mode 100644 index 0000000000..071cb231ba --- /dev/null +++ b/oss-fuzz/dummy-cmd-main.c @@ -0,0 +1,14 @@ +#include "git-compat-util.h" + +/* + * When linking the fuzzers, we link against common-main.o to pick up some + * symbols. However, even though we ignore common-main:main(), we still need to + * provide all the symbols it references. In the fuzzers' case, we need to + * provide a dummy cmd_main() for the linker to be happy. It will never be + * executed. + */ + +int cmd_main(int argc, const char **argv) { + BUG("We should not execute cmd_main() from a fuzz target"); + return 1; +} diff --git a/oss-fuzz/fuzz-date.c b/oss-fuzz/fuzz-date.c new file mode 100644 index 0000000000..036378b946 --- /dev/null +++ b/oss-fuzz/fuzz-date.c @@ -0,0 +1,49 @@ +#include "git-compat-util.h" +#include "date.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + int local; + int num; + char *str; + int16_t tz; + timestamp_t ts; + enum date_mode_type dmtype; + struct date_mode *dm; + + if (size <= 4) + /* + * we use the first byte to fuzz dmtype and the + * second byte to fuzz local, then the next two + * bytes to fuzz tz offset. The remainder + * (at least one byte) is fed as input to + * approxidate_careful(). + */ + return 0; + + local = !!(*data++ & 0x10); + num = *data++ % DATE_UNIX; + if (num >= DATE_STRFTIME) + num++; + dmtype = (enum date_mode_type)num; + size -= 2; + + tz = *data++; + tz = (tz << 8) | *data++; + size -= 2; + + str = xmemdupz(data, size); + + ts = approxidate_careful(str, &num); + free(str); + + dm = date_mode_from_type(dmtype); + dm->local = local; + show_date(ts, (int)tz, dm); + + date_mode_release(dm); + + return 0; +} diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c index f4ecdf8b0e..990a9498d7 100644 --- a/pack-bitmap-write.c +++ b/pack-bitmap-write.c @@ -4,12 +4,9 @@ #include "hex.h" #include "object-store-ll.h" #include "commit.h" -#include "tag.h" #include "diff.h" #include "revision.h" -#include "list-objects.h" #include "progress.h" -#include "pack-revindex.h" #include "pack.h" #include "pack-bitmap.h" #include "hash-lookup.h" @@ -198,6 +195,13 @@ struct bb_commit { unsigned idx; /* within selected array */ }; +static void clear_bb_commit(struct bb_commit *commit) +{ + free_commit_list(commit->reverse_edges); + bitmap_free(commit->commit_mask); + bitmap_free(commit->bitmap); +} + define_commit_slab(bb_data, struct bb_commit); struct bitmap_builder { @@ -339,7 +343,7 @@ next: static void bitmap_builder_clear(struct bitmap_builder *bb) { - clear_bb_data(&bb->data); + deep_clear_bb_data(&bb->data, clear_bb_commit); free(bb->commits); bb->commits_nr = bb->commits_alloc = 0; } diff --git a/pack-bitmap.c b/pack-bitmap.c index 0260890341..2baeabacee 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -51,13 +51,6 @@ struct bitmap_index { struct packed_git *pack; struct multi_pack_index *midx; - /* - * Mark the first `reuse_objects` in the packfile as reused: - * they will be sent as-is without using them for repacking - * calculations - */ - uint32_t reuse_objects; - /* mmapped buffer of the whole bitmap index */ unsigned char *map; size_t map_size; /* size of the mmaped buffer */ @@ -338,7 +331,7 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git, struct stat st; char *bitmap_name = midx_bitmap_filename(midx); int fd = git_open(bitmap_name); - uint32_t i; + uint32_t i, preferred_pack; struct packed_git *preferred; if (fd < 0) { @@ -393,7 +386,12 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git, } } - preferred = bitmap_git->midx->packs[midx_preferred_pack(bitmap_git)]; + if (midx_preferred_pack(bitmap_git->midx, &preferred_pack) < 0) { + warning(_("could not determine MIDX preferred pack")); + goto cleanup; + } + + preferred = bitmap_git->midx->packs[preferred_pack]; if (!is_pack_valid(preferred)) { warning(_("preferred pack (%s) is invalid"), preferred->pack_name); @@ -1280,6 +1278,8 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git, base = fill_in_bitmap(bitmap_git, revs, base, seen); } + object_list_free(¬_mapped); + return base; } @@ -1834,8 +1834,10 @@ cleanup: * -1 means "stop trying further objects"; 0 means we may or may not have * reused, but you can keep feeding bits. */ -static int try_partial_reuse(struct packed_git *pack, - size_t pos, +static int try_partial_reuse(struct bitmap_index *bitmap_git, + struct bitmapped_pack *pack, + size_t bitmap_pos, + uint32_t pack_pos, struct bitmap *reuse, struct pack_window **w_curs) { @@ -1843,40 +1845,18 @@ static int try_partial_reuse(struct packed_git *pack, enum object_type type; unsigned long size; - /* - * try_partial_reuse() is called either on (a) objects in the - * bitmapped pack (in the case of a single-pack bitmap) or (b) - * objects in the preferred pack of a multi-pack bitmap. - * Importantly, the latter can pretend as if only a single pack - * exists because: - * - * - The first pack->num_objects bits of a MIDX bitmap are - * reserved for the preferred pack, and - * - * - Ties due to duplicate objects are always resolved in - * favor of the preferred pack. - * - * Therefore we do not need to ever ask the MIDX for its copy of - * an object by OID, since it will always select it from the - * preferred pack. Likewise, the selected copy of the base - * object for any deltas will reside in the same pack. - * - * This means that we can reuse pos when looking up the bit in - * the reuse bitmap, too, since bits corresponding to the - * preferred pack precede all bits from other packs. - */ - - if (pos >= pack->num_objects) - return -1; /* not actually in the pack or MIDX preferred pack */ + if (pack_pos >= pack->p->num_objects) + return -1; /* not actually in the pack */ - offset = delta_obj_offset = pack_pos_to_offset(pack, pos); - type = unpack_object_header(pack, w_curs, &offset, &size); + offset = delta_obj_offset = pack_pos_to_offset(pack->p, pack_pos); + type = unpack_object_header(pack->p, w_curs, &offset, &size); if (type < 0) return -1; /* broken packfile, punt */ if (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA) { off_t base_offset; uint32_t base_pos; + uint32_t base_bitmap_pos; /* * Find the position of the base object so we can look it up @@ -1886,24 +1866,48 @@ static int try_partial_reuse(struct packed_git *pack, * and the normal slow path will complain about it in * more detail. */ - base_offset = get_delta_base(pack, w_curs, &offset, type, + base_offset = get_delta_base(pack->p, w_curs, &offset, type, delta_obj_offset); if (!base_offset) return 0; - if (offset_to_pack_pos(pack, base_offset, &base_pos) < 0) - return 0; - /* - * We assume delta dependencies always point backwards. This - * lets us do a single pass, and is basically always true - * due to the way OFS_DELTAs work. You would not typically - * find REF_DELTA in a bitmapped pack, since we only bitmap - * packs we write fresh, and OFS_DELTA is the default). But - * let's double check to make sure the pack wasn't written with - * odd parameters. - */ - if (base_pos >= pos) - return 0; + offset_to_pack_pos(pack->p, base_offset, &base_pos); + + if (bitmap_is_midx(bitmap_git)) { + /* + * Cross-pack deltas are rejected for now, but could + * theoretically be supported in the future. + * + * We would need to ensure that we're sending both + * halves of the delta/base pair, regardless of whether + * or not the two cross a pack boundary. If they do, + * then we must convert the delta to an REF_DELTA to + * refer back to the base in the other pack. + * */ + if (midx_pair_to_pack_pos(bitmap_git->midx, + pack->pack_int_id, + base_offset, + &base_bitmap_pos) < 0) { + return 0; + } + } else { + if (offset_to_pack_pos(pack->p, base_offset, + &base_pos) < 0) + return 0; + /* + * We assume delta dependencies always point backwards. + * This lets us do a single pass, and is basically + * always true due to the way OFS_DELTAs work. You would + * not typically find REF_DELTA in a bitmapped pack, + * since we only bitmap packs we write fresh, and + * OFS_DELTA is the default). But let's double check to + * make sure the pack wasn't written with odd + * parameters. + */ + if (base_pos >= pack_pos) + return 0; + base_bitmap_pos = pack->bitmap_pos + base_pos; + } /* * And finally, if we're not sending the base as part of our @@ -1913,77 +1917,89 @@ static int try_partial_reuse(struct packed_git *pack, * to REF_DELTA on the fly. Better to just let the normal * object_entry code path handle it. */ - if (!bitmap_get(reuse, base_pos)) + if (!bitmap_get(reuse, base_bitmap_pos)) return 0; } /* * If we got here, then the object is OK to reuse. Mark it. */ - bitmap_set(reuse, pos); + bitmap_set(reuse, bitmap_pos); return 0; } -uint32_t midx_preferred_pack(struct bitmap_index *bitmap_git) -{ - struct multi_pack_index *m = bitmap_git->midx; - if (!m) - BUG("midx_preferred_pack: requires non-empty MIDX"); - return nth_midxed_pack_int_id(m, pack_pos_to_midx(bitmap_git->midx, 0)); -} - -int reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git, - struct packed_git **packfile_out, - uint32_t *entries, - struct bitmap **reuse_out) +static void reuse_partial_packfile_from_bitmap_1(struct bitmap_index *bitmap_git, + struct bitmapped_pack *pack, + struct bitmap *reuse) { - struct repository *r = the_repository; - struct packed_git *pack; struct bitmap *result = bitmap_git->result; - struct bitmap *reuse; struct pack_window *w_curs = NULL; - size_t i = 0; - uint32_t offset; - uint32_t objects_nr; + size_t pos = pack->bitmap_pos / BITS_IN_EWORD; - assert(result); + if (!pack->bitmap_pos) { + /* + * If we're processing the first (in the case of a MIDX, the + * preferred pack) or the only (in the case of single-pack + * bitmaps) pack, then we can reuse whole words at a time. + * + * This is because we know that any deltas in this range *must* + * have their bases chosen from the same pack, since: + * + * - In the single pack case, there is no other pack to choose + * them from. + * + * - In the MIDX case, the first pack is the preferred pack, so + * all ties are broken in favor of that pack (i.e. the one + * we're currently processing). So any duplicate bases will be + * resolved in favor of the pack we're processing. + */ + while (pos < result->word_alloc && + pos < pack->bitmap_nr / BITS_IN_EWORD && + result->words[pos] == (eword_t)~0) + pos++; + memset(reuse->words, 0xFF, pos * sizeof(eword_t)); + } - load_reverse_index(r, bitmap_git); + for (; pos < result->word_alloc; pos++) { + eword_t word = result->words[pos]; + size_t offset; - if (bitmap_is_midx(bitmap_git)) - pack = bitmap_git->midx->packs[midx_preferred_pack(bitmap_git)]; - else - pack = bitmap_git->pack; - objects_nr = pack->num_objects; + for (offset = 0; offset < BITS_IN_EWORD; offset++) { + size_t bit_pos; + uint32_t pack_pos; - while (i < result->word_alloc && result->words[i] == (eword_t)~0) - i++; + if (word >> offset == 0) + break; - /* - * Don't mark objects not in the packfile or preferred pack. This bitmap - * marks objects eligible for reuse, but the pack-reuse code only - * understands how to reuse a single pack. Since the preferred pack is - * guaranteed to have all bases for its deltas (in a multi-pack bitmap), - * we use it instead of another pack. In single-pack bitmaps, the choice - * is made for us. - */ - if (i > objects_nr / BITS_IN_EWORD) - i = objects_nr / BITS_IN_EWORD; + offset += ewah_bit_ctz64(word >> offset); + + bit_pos = pos * BITS_IN_EWORD + offset; + if (bit_pos < pack->bitmap_pos) + continue; + if (bit_pos >= pack->bitmap_pos + pack->bitmap_nr) + goto done; - reuse = bitmap_word_alloc(i); - memset(reuse->words, 0xFF, i * sizeof(eword_t)); + if (bitmap_is_midx(bitmap_git)) { + uint32_t midx_pos; + off_t ofs; - for (; i < result->word_alloc; ++i) { - eword_t word = result->words[i]; - size_t pos = (i * BITS_IN_EWORD); + midx_pos = pack_pos_to_midx(bitmap_git->midx, bit_pos); + ofs = nth_midxed_offset(bitmap_git->midx, midx_pos); - for (offset = 0; offset < BITS_IN_EWORD; ++offset) { - if ((word >> offset) == 0) - break; + if (offset_to_pack_pos(pack->p, ofs, &pack_pos) < 0) + BUG("could not find object in pack %s " + "at offset %"PRIuMAX" in MIDX", + pack_basename(pack->p), (uintmax_t)ofs); + } else { + pack_pos = cast_size_t_to_uint32_t(st_sub(bit_pos, pack->bitmap_pos)); + if (pack_pos >= pack->p->num_objects) + BUG("advanced beyond the end of pack %s (%"PRIuMAX" > %"PRIu32")", + pack_basename(pack->p), (uintmax_t)pack_pos, + pack->p->num_objects); + } - offset += ewah_bit_ctz64(word >> offset); - if (try_partial_reuse(pack, pos + offset, - reuse, &w_curs) < 0) { + if (try_partial_reuse(bitmap_git, pack, bit_pos, + pack_pos, reuse, &w_curs) < 0) { /* * try_partial_reuse indicated we couldn't reuse * any bits, so there is no point in trying more @@ -2000,11 +2016,97 @@ int reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git, done: unuse_pack(&w_curs); +} - *entries = bitmap_popcount(reuse); - if (!*entries) { - bitmap_free(reuse); +static int bitmapped_pack_cmp(const void *va, const void *vb) +{ + const struct bitmapped_pack *a = va; + const struct bitmapped_pack *b = vb; + + if (a->bitmap_pos < b->bitmap_pos) return -1; + if (a->bitmap_pos > b->bitmap_pos) + return 1; + return 0; +} + +void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git, + struct bitmapped_pack **packs_out, + size_t *packs_nr_out, + struct bitmap **reuse_out, + int multi_pack_reuse) +{ + struct repository *r = the_repository; + struct bitmapped_pack *packs = NULL; + struct bitmap *result = bitmap_git->result; + struct bitmap *reuse; + size_t i; + size_t packs_nr = 0, packs_alloc = 0; + size_t word_alloc; + uint32_t objects_nr = 0; + + assert(result); + + load_reverse_index(r, bitmap_git); + + if (bitmap_is_midx(bitmap_git)) { + for (i = 0; i < bitmap_git->midx->num_packs; i++) { + struct bitmapped_pack pack; + if (nth_bitmapped_pack(r, bitmap_git->midx, &pack, i) < 0) { + warning(_("unable to load pack: '%s', disabling pack-reuse"), + bitmap_git->midx->pack_names[i]); + free(packs); + return; + } + + if (!pack.bitmap_nr) + continue; + + if (!multi_pack_reuse && pack.bitmap_pos) { + /* + * If we're only reusing a single pack, skip + * over any packs which are not positioned at + * the beginning of the MIDX bitmap. + * + * This is consistent with the existing + * single-pack reuse behavior, which only reuses + * parts of the MIDX's preferred pack. + */ + continue; + } + + ALLOC_GROW(packs, packs_nr + 1, packs_alloc); + memcpy(&packs[packs_nr++], &pack, sizeof(pack)); + + objects_nr += pack.p->num_objects; + + if (!multi_pack_reuse) + break; + } + + QSORT(packs, packs_nr, bitmapped_pack_cmp); + } else { + ALLOC_GROW(packs, packs_nr + 1, packs_alloc); + + packs[packs_nr].p = bitmap_git->pack; + packs[packs_nr].bitmap_nr = bitmap_git->pack->num_objects; + packs[packs_nr].bitmap_pos = 0; + + objects_nr = packs[packs_nr++].bitmap_nr; + } + + word_alloc = objects_nr / BITS_IN_EWORD; + if (objects_nr % BITS_IN_EWORD) + word_alloc++; + reuse = bitmap_word_alloc(word_alloc); + + for (i = 0; i < packs_nr; i++) + reuse_partial_packfile_from_bitmap_1(bitmap_git, &packs[i], reuse); + + if (bitmap_is_empty(reuse)) { + free(packs); + bitmap_free(reuse); + return; } /* @@ -2012,9 +2114,9 @@ done: * need to be handled separately. */ bitmap_and_not(result, reuse); - *packfile_out = pack; + *packs_out = packs; + *packs_nr_out = packs_nr; *reuse_out = reuse; - return 0; } int bitmap_walk_contains(struct bitmap_index *bitmap_git, diff --git a/pack-bitmap.h b/pack-bitmap.h index 5273a6a019..c7dea13217 100644 --- a/pack-bitmap.h +++ b/pack-bitmap.h @@ -52,6 +52,15 @@ typedef int (*show_reachable_fn)( struct bitmap_index; +struct bitmapped_pack { + struct packed_git *p; + + uint32_t bitmap_pos; + uint32_t bitmap_nr; + + uint32_t pack_int_id; /* MIDX only */ +}; + struct bitmap_index *prepare_bitmap_git(struct repository *r); struct bitmap_index *prepare_midx_bitmap_git(struct multi_pack_index *midx); void count_bitmap_commit_list(struct bitmap_index *, uint32_t *commits, @@ -68,11 +77,11 @@ int test_bitmap_hashes(struct repository *r); struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs, int filter_provided_objects); -uint32_t midx_preferred_pack(struct bitmap_index *bitmap_git); -int reuse_partial_packfile_from_bitmap(struct bitmap_index *, - struct packed_git **packfile, - uint32_t *entries, - struct bitmap **reuse_out); +void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git, + struct bitmapped_pack **packs_out, + size_t *packs_nr_out, + struct bitmap **reuse_out, + int multi_pack_reuse); int rebuild_existing_bitmaps(struct bitmap_index *, struct packing_data *mapping, kh_oid_map_t *reused_bitmaps, int show_progress); void free_bitmap_index(struct bitmap_index *); diff --git a/pack-check.c b/pack-check.c index 977f619618..25104d5b14 100644 --- a/pack-check.c +++ b/pack-check.c @@ -3,7 +3,6 @@ #include "hex.h" #include "repository.h" #include "pack.h" -#include "pack-revindex.h" #include "progress.h" #include "packfile.h" #include "object-file.h" diff --git a/pack-objects.c b/pack-objects.c index f403ca6986..a9d9855063 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -151,6 +151,21 @@ void prepare_packing_data(struct repository *r, struct packing_data *pdata) init_recursive_mutex(&pdata->odb_lock); } +void clear_packing_data(struct packing_data *pdata) +{ + if (!pdata) + return; + + free(pdata->cruft_mtime); + free(pdata->in_pack); + free(pdata->in_pack_by_idx); + free(pdata->in_pack_pos); + free(pdata->index); + free(pdata->layer); + free(pdata->objects); + free(pdata->tree_depth); +} + struct object_entry *packlist_alloc(struct packing_data *pdata, const struct object_id *oid) { diff --git a/pack-objects.h b/pack-objects.h index 0d78db40cb..b9898a4e64 100644 --- a/pack-objects.h +++ b/pack-objects.h @@ -169,6 +169,7 @@ struct packing_data { }; void prepare_packing_data(struct repository *r, struct packing_data *pdata); +void clear_packing_data(struct packing_data *pdata); /* Protect access to object database */ static inline void packing_data_lock(struct packing_data *pdata) diff --git a/pack-revindex.c b/pack-revindex.c index acf1dd9786..a7624d8be8 100644 --- a/pack-revindex.c +++ b/pack-revindex.c @@ -520,19 +520,12 @@ static int midx_pack_order_cmp(const void *va, const void *vb) return 0; } -int midx_to_pack_pos(struct multi_pack_index *m, uint32_t at, uint32_t *pos) +static int midx_key_to_pack_pos(struct multi_pack_index *m, + struct midx_pack_key *key, + uint32_t *pos) { - struct midx_pack_key key; uint32_t *found; - if (!m->revindex_data) - BUG("midx_to_pack_pos: reverse index not yet loaded"); - if (m->num_objects <= at) - BUG("midx_to_pack_pos: out-of-bounds object at %"PRIu32, at); - - key.pack = nth_midxed_pack_int_id(m, at); - key.offset = nth_midxed_offset(m, at); - key.midx = m; /* * The preferred pack sorts first, so determine its identifier by * looking at the first object in pseudo-pack order. @@ -542,14 +535,43 @@ int midx_to_pack_pos(struct multi_pack_index *m, uint32_t at, uint32_t *pos) * implicitly is preferred (and includes all its objects, since ties are * broken first by pack identifier). */ - key.preferred_pack = nth_midxed_pack_int_id(m, pack_pos_to_midx(m, 0)); + if (midx_preferred_pack(key->midx, &key->preferred_pack) < 0) + return error(_("could not determine preferred pack")); - found = bsearch(&key, m->revindex_data, m->num_objects, - sizeof(*m->revindex_data), midx_pack_order_cmp); + found = bsearch(key, m->revindex_data, m->num_objects, + sizeof(*m->revindex_data), + midx_pack_order_cmp); if (!found) - return error("bad offset for revindex"); + return -1; *pos = found - m->revindex_data; return 0; } + +int midx_to_pack_pos(struct multi_pack_index *m, uint32_t at, uint32_t *pos) +{ + struct midx_pack_key key; + + if (!m->revindex_data) + BUG("midx_to_pack_pos: reverse index not yet loaded"); + if (m->num_objects <= at) + BUG("midx_to_pack_pos: out-of-bounds object at %"PRIu32, at); + + key.pack = nth_midxed_pack_int_id(m, at); + key.offset = nth_midxed_offset(m, at); + key.midx = m; + + return midx_key_to_pack_pos(m, &key, pos); +} + +int midx_pair_to_pack_pos(struct multi_pack_index *m, uint32_t pack_int_id, + off_t ofs, uint32_t *pos) +{ + struct midx_pack_key key = { + .pack = pack_int_id, + .offset = ofs, + .midx = m, + }; + return midx_key_to_pack_pos(m, &key, pos); +} diff --git a/pack-revindex.h b/pack-revindex.h index 6dd47efea1..422c2487ae 100644 --- a/pack-revindex.h +++ b/pack-revindex.h @@ -142,4 +142,7 @@ uint32_t pack_pos_to_midx(struct multi_pack_index *m, uint32_t pos); */ int midx_to_pack_pos(struct multi_pack_index *midx, uint32_t at, uint32_t *pos); +int midx_pair_to_pack_pos(struct multi_pack_index *midx, uint32_t pack_id, + off_t ofs, uint32_t *pos); + #endif diff --git a/pack-write.c b/pack-write.c index b19ddf15b2..80ecfa544c 100644 --- a/pack-write.c +++ b/pack-write.c @@ -7,7 +7,6 @@ #include "remote.h" #include "chunk-format.h" #include "pack-mtimes.h" -#include "oidmap.h" #include "pack-objects.h" #include "pack-revindex.h" #include "path.h" diff --git a/packfile.c b/packfile.c index 9cc0a2e37a..84a005674d 100644 --- a/packfile.c +++ b/packfile.c @@ -9,7 +9,6 @@ #include "mergesort.h" #include "packfile.h" #include "delta.h" -#include "streaming.h" #include "hash-lookup.h" #include "commit.h" #include "object.h" diff --git a/packfile.h b/packfile.h index c3692308b8..28c8fd3e39 100644 --- a/packfile.h +++ b/packfile.h @@ -54,7 +54,7 @@ const char *pack_basename(struct packed_git *p); struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path); typedef void each_file_in_pack_dir_fn(const char *full_path, size_t full_path_len, - const char *file_pach, void *data); + const char *file_name, void *data); void for_each_file_in_pack_dir(const char *objdir, each_file_in_pack_dir_fn fn, void *data); diff --git a/parse-options.c b/parse-options.c index e0c94b0546..63a99dea6e 100644 --- a/parse-options.c +++ b/parse-options.c @@ -2,8 +2,6 @@ #include "parse-options.h" #include "abspath.h" #include "parse.h" -#include "commit.h" -#include "color.h" #include "gettext.h" #include "strbuf.h" #include "string-list.h" @@ -279,7 +277,8 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p, opt_name = optnamearg(opt, arg, flags); other_opt_name = optnamearg(elem->opt, elem->arg, elem->flags); - error(_("%s is incompatible with %s"), opt_name, other_opt_name); + error(_("options '%s' and '%s' cannot be used together"), + opt_name, other_opt_name); free(opt_name); free(other_opt_name); return -1; @@ -358,6 +357,7 @@ static enum parse_opt_result parse_long_opt( const char *arg_end = strchrnul(arg, '='); const struct option *abbrev_option = NULL, *ambiguous_option = NULL; enum opt_parsed abbrev_flags = OPT_LONG, ambiguous_flags = OPT_LONG; + int allow_abbrev = !(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT); for (; options->type != OPTION_END; options++) { const char *rest, *long_name = options->long_name; @@ -368,12 +368,16 @@ static enum parse_opt_result parse_long_opt( if (!long_name) continue; -again: + if (!starts_with(arg, "no-") && + !(options->flags & PARSE_OPT_NONEG) && + skip_prefix(long_name, "no-", &long_name)) + opt_flags |= OPT_UNSET; + if (!skip_prefix(arg, long_name, &rest)) rest = NULL; if (!rest) { /* abbreviated? */ - if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT) && + if (allow_abbrev && !strncmp(long_name, arg, arg_end - arg)) { is_abbreviated: if (abbrev_option && @@ -397,22 +401,18 @@ is_abbreviated: if (options->flags & PARSE_OPT_NONEG) continue; /* negated and abbreviated very much? */ - if (starts_with("no-", arg)) { + if (allow_abbrev && starts_with("no-", arg)) { flags |= OPT_UNSET; goto is_abbreviated; } /* negated? */ - if (!starts_with(arg, "no-")) { - if (skip_prefix(long_name, "no-", &long_name)) { - opt_flags |= OPT_UNSET; - goto again; - } + if (!starts_with(arg, "no-")) continue; - } flags |= OPT_UNSET; if (!skip_prefix(arg + 3, long_name, &rest)) { /* abbreviated and negated? */ - if (starts_with(long_name, arg + 3)) + if (allow_abbrev && + starts_with(long_name, arg + 3)) goto is_abbreviated; else continue; @@ -929,13 +929,18 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx, continue; } - if (!arg[2] /* "--" */ || - !strcmp(arg + 2, "end-of-options")) { + if (!arg[2] /* "--" */) { if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) { ctx->argc--; ctx->argv++; } break; + } else if (!strcmp(arg + 2, "end-of-options")) { + if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)) { + ctx->argc--; + ctx->argv++; + } + break; } if (internal_help && !strcmp(arg + 2, "help-all")) diff --git a/patch-ids.c b/patch-ids.c index c3e1a0dd21..a5683b462c 100644 --- a/patch-ids.c +++ b/patch-ids.c @@ -2,7 +2,6 @@ #include "diff.h" #include "commit.h" #include "hash.h" -#include "hash-lookup.h" #include "hex.h" #include "patch-ids.h" @@ -871,7 +871,7 @@ const char *enter_repo(const char *path, int strict) return NULL; } -static int calc_shared_perm(int mode) +int calc_shared_perm(int mode) { int tweak; @@ -1588,7 +1588,5 @@ REPO_GIT_PATH_FUNC(merge_msg, "MERGE_MSG") REPO_GIT_PATH_FUNC(merge_rr, "MERGE_RR") REPO_GIT_PATH_FUNC(merge_mode, "MERGE_MODE") REPO_GIT_PATH_FUNC(merge_head, "MERGE_HEAD") -REPO_GIT_PATH_FUNC(merge_autostash, "MERGE_AUTOSTASH") -REPO_GIT_PATH_FUNC(auto_merge, "AUTO_MERGE") REPO_GIT_PATH_FUNC(fetch_head, "FETCH_HEAD") REPO_GIT_PATH_FUNC(shallow, "shallow") @@ -175,14 +175,13 @@ const char *git_path_merge_msg(struct repository *r); const char *git_path_merge_rr(struct repository *r); const char *git_path_merge_mode(struct repository *r); const char *git_path_merge_head(struct repository *r); -const char *git_path_merge_autostash(struct repository *r); -const char *git_path_auto_merge(struct repository *r); const char *git_path_fetch_head(struct repository *r); const char *git_path_shallow(struct repository *r); int ends_with_path_components(const char *path, const char *components); int validate_headref(const char *ref); +int calc_shared_perm(int mode); int adjust_shared_perm(const char *path); char *interpolate_path(const char *path, int real_home); diff --git a/pathspec.c b/pathspec.c index bb1efe1f39..2133b9fe60 100644 --- a/pathspec.c +++ b/pathspec.c @@ -109,16 +109,37 @@ static struct pathspec_magic { { PATHSPEC_ATTR, '\0', "attr" }, }; -static void prefix_magic(struct strbuf *sb, int prefixlen, unsigned magic) +static void prefix_magic(struct strbuf *sb, int prefixlen, + unsigned magic, const char *element) { - int i; - strbuf_addstr(sb, ":("); - for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++) - if (magic & pathspec_magic[i].bit) { - if (sb->buf[sb->len - 1] != '(') - strbuf_addch(sb, ','); - strbuf_addstr(sb, pathspec_magic[i].name); + /* No magic was found in element, just add prefix magic */ + if (!magic) { + strbuf_addf(sb, ":(prefix:%d)", prefixlen); + return; + } + + /* + * At this point, we know that parse_element_magic() was able + * to extract some pathspec magic from element. So we know + * element is correctly formatted in either shorthand or + * longhand form + */ + if (element[1] != '(') { + /* Process an element in shorthand form (e.g. ":!/<match>") */ + strbuf_addstr(sb, ":("); + for (int i = 0; i < ARRAY_SIZE(pathspec_magic); i++) { + if ((magic & pathspec_magic[i].bit) && + pathspec_magic[i].mnemonic) { + if (sb->buf[sb->len - 1] != '(') + strbuf_addch(sb, ','); + strbuf_addstr(sb, pathspec_magic[i].name); + } } + } else { + /* For the longhand form, we copy everything up to the final ')' */ + size_t len = strchr(element, ')') - element; + strbuf_add(sb, element, len); + } strbuf_addf(sb, ",prefix:%d)", prefixlen); } @@ -493,7 +514,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags, struct strbuf sb = STRBUF_INIT; /* Preserve the actual prefix length of each pattern */ - prefix_magic(&sb, prefixlen, element_magic); + prefix_magic(&sb, prefixlen, element_magic, elt); strbuf_addstr(&sb, match); item->original = strbuf_detach(&sb, NULL); diff --git a/perl/FromCPAN/Error.pm b/perl/FromCPAN/Error.pm index d82b71325c..5b97e0315d 100644 --- a/perl/FromCPAN/Error.pm +++ b/perl/FromCPAN/Error.pm @@ -1025,7 +1025,7 @@ C<:warndie> handlers added by Paul Evans <leonerd@leonerd.org.uk> =head1 MAINTAINER -Shlomi Fish, L<http://www.shlomifish.org/> . +Shlomi Fish, L<https://www.shlomifish.org/> . =head1 PAST MAINTAINERS diff --git a/perl/Git.pm b/perl/Git.pm index 117765dc73..03bf570bf4 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -7,7 +7,7 @@ Git - Perl interface to the Git version control system package Git; -use 5.008; +use 5.008001; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); diff --git a/perl/Git/I18N.pm b/perl/Git/I18N.pm index 895e759c57..5454c3a6d2 100644 --- a/perl/Git/I18N.pm +++ b/perl/Git/I18N.pm @@ -1,5 +1,5 @@ package Git::I18N; -use 5.008; +use 5.008001; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); BEGIN { diff --git a/perl/Git/LoadCPAN.pm b/perl/Git/LoadCPAN.pm index 0c360bc799..8c7fa805f9 100644 --- a/perl/Git/LoadCPAN.pm +++ b/perl/Git/LoadCPAN.pm @@ -1,5 +1,5 @@ package Git::LoadCPAN; -use 5.008; +use 5.008001; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); diff --git a/perl/Git/LoadCPAN/Error.pm b/perl/Git/LoadCPAN/Error.pm index 5d84c20288..5cecb0fcd6 100644 --- a/perl/Git/LoadCPAN/Error.pm +++ b/perl/Git/LoadCPAN/Error.pm @@ -1,5 +1,5 @@ package Git::LoadCPAN::Error; -use 5.008; +use 5.008001; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); use Git::LoadCPAN ( diff --git a/perl/Git/LoadCPAN/Mail/Address.pm b/perl/Git/LoadCPAN/Mail/Address.pm index 340e88a7a5..9f808090a6 100644 --- a/perl/Git/LoadCPAN/Mail/Address.pm +++ b/perl/Git/LoadCPAN/Mail/Address.pm @@ -1,5 +1,5 @@ package Git::LoadCPAN::Mail::Address; -use 5.008; +use 5.008001; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); use Git::LoadCPAN ( diff --git a/perl/Git/Packet.pm b/perl/Git/Packet.pm index d144f5168f..d896e69523 100644 --- a/perl/Git/Packet.pm +++ b/perl/Git/Packet.pm @@ -1,5 +1,5 @@ package Git::Packet; -use 5.008; +use 5.008001; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); BEGIN { diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm index 6ce2e283c8..7721708ce5 100644 --- a/perl/Git/SVN.pm +++ b/perl/Git/SVN.pm @@ -1752,7 +1752,7 @@ sub tie_for_persistent_memoization { END { # Force cache writeout explicitly instead of waiting for # global destruction to avoid segfault in Storable: - # http://rt.cpan.org/Public/Bug/Display.html?id=36087 + # https://rt.cpan.org/Public/Bug/Display.html?id=36087 unmemoize_svn_mergeinfo_functions(); } diff --git a/pkt-line.c b/pkt-line.c index af83a19f4d..24479eae4d 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -4,6 +4,7 @@ #include "gettext.h" #include "hex.h" #include "run-command.h" +#include "sideband.h" #include "trace.h" #include "write-or-die.h" @@ -462,8 +463,32 @@ enum packet_read_status packet_read_with_status(int fd, char **src_buffer, } if ((options & PACKET_READ_CHOMP_NEWLINE) && - len && buffer[len-1] == '\n') - len--; + len && buffer[len-1] == '\n') { + if (options & PACKET_READ_USE_SIDEBAND) { + int band = *buffer & 0xff; + switch (band) { + case 1: + /* Chomp newline for payload */ + len--; + break; + case 2: + case 3: + /* + * Do not chomp newline for progress and error + * message. + */ + break; + default: + /* + * Bad sideband, let's leave it to + * demultiplex_sideband() to catch this error. + */ + break; + } + } else { + len--; + } + } buffer[len] = 0; if (options & PACKET_READ_REDACT_URI_PATH && @@ -592,17 +617,19 @@ void packet_reader_init(struct packet_reader *reader, int fd, reader->options = options; reader->me = "git"; reader->hash_algo = &hash_algos[GIT_HASH_SHA1]; + strbuf_init(&reader->scratch, 0); } enum packet_read_status packet_reader_read(struct packet_reader *reader) { - struct strbuf scratch = STRBUF_INIT; - if (reader->line_peeked) { reader->line_peeked = 0; return reader->status; } + if (reader->use_sideband) + reader->options |= PACKET_READ_USE_SIDEBAND; + /* * Consume all progress packets until a primary payload packet is * received @@ -620,7 +647,7 @@ enum packet_read_status packet_reader_read(struct packet_reader *reader) break; if (demultiplex_sideband(reader->me, reader->status, reader->buffer, reader->pktlen, 1, - &scratch, &sideband_type)) + &reader->scratch, &sideband_type)) break; } diff --git a/pkt-line.h b/pkt-line.h index 954eec8719..3b33cc64f3 100644 --- a/pkt-line.h +++ b/pkt-line.h @@ -2,7 +2,6 @@ #define PKTLINE_H #include "strbuf.h" -#include "sideband.h" /* * Write a packetized stream, where each line is preceded by @@ -85,6 +84,7 @@ void packet_fflush(FILE *f); #define PACKET_READ_DIE_ON_ERR_PACKET (1u<<2) #define PACKET_READ_GENTLE_ON_READ_ERROR (1u<<3) #define PACKET_READ_REDACT_URI_PATH (1u<<4) +#define PACKET_READ_USE_SIDEBAND (1u<<5) int packet_read(int fd, char *buffer, unsigned size, int options); /* @@ -194,6 +194,9 @@ struct packet_reader { /* hash algorithm in use */ const struct git_hash_algo *hash_algo; + + /* hold temporary sideband message */ + struct strbuf scratch; }; /* @@ -1,7 +1,7 @@ # Bulgarian translation of git po-file. -# Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Alexander Shopov <ash@kambanaria.org>. +# Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Alexander Shopov <ash@kambanaria.org>. # This file is distributed under the same license as the git package. -# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023. +# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024. # ======================== # DICTIONARY TO MERGE IN GIT GUI # ------------------------ @@ -136,11 +136,13 @@ # island marks граници на групите # reflog журнал на указателите # hash контролна Ñума, изчиÑлÑване на контролна Ñума -# fanout Ð¾Ñ‚ÐºÑŠÑ (разперване???) +# fanout Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° разпределÑне # idx - index of pack file, 1 index per 1 packfile # midx, multi-pack index - файл Ñ Ð¸Ð½Ð´ÐµÐºÑа за множеÑтво пакети # overlay mode - припокриващ режим (при изтеглÑнe) # incremental file нараÑтващ файл +# commit-graph граф Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ +# commit-graph chain верига на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ # split (commit-graphr) раздробен (граф Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ) # clobber (a tag) презапиÑвам (етикет) # blame извеждане на авторÑтво @@ -187,6 +189,9 @@ # timestamp времево клеймо # bare repository голо хранилище # resolve-undo отмÑна на разрешените Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ +# resolve conflict коригирам конфликт +# resolve reference уÑтановÑване на обекта, Ñочен от указателÑ, проÑледÑване на ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ +# cannot resolve reference не може да Ñее открие към какво Ñочи указателÑÑ‚ # maintenance задачи по поддръжка # GLE поÑледна грешка в нишката - от GetLatError: https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror # lookup table таблица ÑÑŠÑ ÑъответÑÑ‚Ð²Ð¸Ñ @@ -201,13 +206,35 @@ # superproject Ñвръхпроект # rev-index обратен Ð¸Ð½Ð´ÐµÐºÑ (reverse index) # dererging branches раздалечили Ñе клони +# master/main branch оÑновен клон +# unborn/orphan branch неродѐн клон (а не неÑъздаден) - клон без никакви подаваниÑ, включително и началното +# parse анализ, анализирам +# reinitialize repository занулÑване на хранилището и инициализиране +# replay изпълнÑване/прилагане наново +# BTMP chunk Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° побитова маÑка +# OID fanout chunk Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° разпределÑнето +# OID lookup chunk Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° търÑенето +# autostash автоматично Ñкатано +# symref файл Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ» (regular file that stores a string that begins with ref: refs/) +# +# +# # ------------------------ # „$var“ - може да не Ñработва за shell има gettext и eval_gettext - проверка - намират Ñе леÑно по „$ # ------------------------ +# Ñ‚Ð°Ð±ÑƒÐ»Ð°Ñ†Ð¸Ñ Ð² началото на реда Ñе Ð·Ð°Ð¼ÐµÐ½Ñ Ñ Ñ‡ÐµÑ‚Ð¸Ñ€Ð¸ интервала +# по подобен начин отÑтъпът на примерна команда е четири интервала +# ------------------------ +# # FIXME -# HEAD as a reference vs head of a branch -# git update-index -h извежда Ñамо един ред, а не цÑлата помощ за опциите # git fetch --al работи подобно на --all +# +# ---- +# +# TODO +# ПричаÑтно-Ñтрадателни форми (бъде отворен) -> Възвратно-Ñтрадателни форми (Ñе отвори) +# <ТЕРМИÐ> -> ТЕРМИР+# # ------------------------ # export PO_FILE=bg.po # msgattrib --only-fuzzy $PO_FILE > todo1.po @@ -217,10 +244,10 @@ # for i in `sort -u FILES`; do cnt=`grep $i FILES | wc -l`; echo $cnt $i ;done | sort -n msgid "" msgstr "" -"Project-Id-Version: git 2.41\n" +"Project-Id-Version: git 2.44\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-05-19 19:48+0200\n" -"PO-Revision-Date: 2023-05-19 20:57+0300\n" +"POT-Creation-Date: 2024-02-16 09:33+0100\n" +"PO-Revision-Date: 2024-02-16 09:38+0100\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -234,7 +261,7 @@ msgid "Huh (%s)?" msgstr "ÐеуÑпешен анализ — „%s“." msgid "could not read index" -msgstr "индекÑÑŠÑ‚ не може да бъде прочетен" +msgstr "индекÑÑŠÑ‚ не може да Ñе прочете" msgid "binary" msgstr "двоично" @@ -253,7 +280,7 @@ msgid "could not stage '%s'" msgstr "неуÑпешно добавÑне в индекÑа на „%s“" msgid "could not write index" -msgstr "индекÑÑŠÑ‚ не може да бъде запиÑан" +msgstr "индекÑÑŠÑ‚ не може да Ñе запише" #, c-format msgid "updated %d path\n" @@ -273,7 +300,7 @@ msgid "Revert" msgstr "ОтмÑна" msgid "Could not parse HEAD^{tree}" -msgstr "УказателÑÑ‚ „HEAD^{tree}“ не може да бъде анализиран" +msgstr "УказателÑÑ‚ „HEAD^{tree}“ не може да Ñе анализира" #, c-format msgid "reverted %d path\n" @@ -376,7 +403,7 @@ msgid "path" msgstr "път" msgid "could not refresh index" -msgstr "индекÑÑŠÑ‚ не може да бъде обновен" +msgstr "индекÑÑŠÑ‚ не може да Ñе обнови" #, c-format msgid "Bye.\n" @@ -402,8 +429,8 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "staging." msgstr "" -"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче ще бъде незабавно " -"добавено към индекÑа." +"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче незабавно ще Ñе " +"добави към индекÑа." msgid "" "y - stage this hunk\n" @@ -438,8 +465,8 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "stashing." msgstr "" -"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче ще бъде незабавно " -"Ñкътано." +"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче незабавно ще Ñе " +"Ñкатае." msgid "" "y - stash this hunk\n" @@ -474,8 +501,8 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "unstaging." msgstr "" -"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче ще бъде незабавно " -"извадено от индекÑа." +"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче незабавно ще Ñе " +"извади от индекÑа." msgid "" "y - unstage this hunk\n" @@ -511,8 +538,8 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "applying." msgstr "" -"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче ще бъде незабавно " -"набелÑзано за прилагане." +"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче незабавно ще Ñе " +"набележи за прилагане." msgid "" "y - apply this hunk to index\n" @@ -549,8 +576,8 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "discarding." msgstr "" -"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче ще бъде незабавно " -"набелÑзано за занулÑване." +"Ðко кръпката може да Ñе приложи чиÑто, редактираното парче незабавно ще Ñе " +"набележи за занулÑване." msgid "" "y - discard this hunk from worktree\n" @@ -728,7 +755,7 @@ msgstr "" "За да пропуÑнете редовете, започващи Ñ â€ž%c“: заменете знака Ñ â€ž “ (Ñтават " "контекÑÑ‚)\n" "За да пропуÑнете редовете, започващи Ñ â€ž%c“: изтрийте ги.\n" -"Редовете, които започват Ñ â€ž%c“ ще бъдат пропуÑнати.\n" +"Редовете, които започват Ñ â€ž%c“ ще Ñе пропуÑнат.\n" msgid "" "If it does not apply cleanly, you will be given an opportunity to\n" @@ -736,7 +763,7 @@ msgid "" "aborted and the hunk is left unchanged.\n" msgstr "" "Ðко е невъзможно чиÑто прилагане на кода, ще може пак да редактирате. Ðко\n" -"изтриете вÑички редове от парчето код, то ще бъде оÑтавено непроменено, а\n" +"изтриете вÑички редове от парчето код, то ще Ñе оÑтави непроменено, а\n" "редактирането — отказано.\n" msgid "could not parse hunk header" @@ -827,14 +854,14 @@ msgid "No hunk matches the given pattern" msgstr "Ðикое парче не напаÑва на регулÑÑ€Ð½Ð¸Ñ Ð¸Ð·Ñ€Ð°Ð·" msgid "Sorry, cannot split this hunk" -msgstr "Това парче не може да бъде разделено" +msgstr "Това парче не може да Ñе раздели" #, c-format msgid "Split into %d hunks." msgstr "РазделÑне на %d парчета." msgid "Sorry, cannot edit this hunk" -msgstr "Това парче не може да бъде редактирано" +msgstr "Това парче не може да Ñе редактира" msgid "'git apply' failed" msgstr "неуÑпешно изпълнение на „git apply“" @@ -868,9 +895,8 @@ msgstr "Издърпването е блокирано от неÑлети фаРmsgid "Reverting is not possible because you have unmerged files." msgstr "ОтмÑната е блокирана от неÑлети файлове." -#, c-format -msgid "It is not possible to %s because you have unmerged files." -msgstr "ДейÑтвието „%s“ е блокирано от неÑлети файлове." +msgid "Rebasing is not possible because you have unmerged files." +msgstr "Пребазирането е блокирано от неÑлети файлове." msgid "" "Fix them up in the work tree, and then use 'git add/rm <file>'\n" @@ -902,11 +928,11 @@ msgid "" msgstr "" "Раздалечили Ñе клони не може да Ñе превъртÑÑ‚. Ползвайте:\n" "\n" -" git merge --no-ff\n" +" git merge --no-ff\n" "\n" "или:\n" "\n" -" git rebase\n" +" git rebase\n" msgid "Not possible to fast-forward, aborting." msgstr "Ðе може да Ñе извърши превъртане, преуÑтановÑване на дейÑтвието." @@ -953,9 +979,8 @@ msgstr "" "Бележка: преминаване към „%s“.\n" "\n" "УказателÑÑ‚ „HEAD“ не е Ñвързан. Може да разглеждате, да правите произволни\n" -"промѐни и да ги подавате. Ðко изтеглите нещо друго, вÑички промѐни ще " -"бъдат\n" -"забравени и никой клон нÑма да Ñе промѐни.\n" +"промѐни и да ги подавате. Ðко изтеглите нещо друго, вÑички промѐни ще Ñе\n" +"забравÑÑ‚ и никой клон нÑма да Ñе промѐни.\n" "\n" "Ðко иÑкате да Ñъздадете нов клон, за да запазите подаваниÑта Ñи, може да\n" "направите това като зададете име на клон към опциÑта „-c“ на командата\n" @@ -1019,9 +1044,15 @@ msgstr "опциите „%s“ и „%s“ Ñа неÑъвмеÑтими" msgid "'%s' outside a repository" msgstr "„%s“ извън хранилище" +msgid "failed to read patch" +msgstr "кръпката не може да Ñе прочете" + +msgid "patch too large" +msgstr "твърде голÑма кръпка" + #, c-format msgid "Cannot prepare timestamp regexp %s" -msgstr "РегулÑрниÑÑ‚ израз за времевото клеймо „%s“ не може за бъде компилиран" +msgstr "РегулÑрниÑÑ‚ израз за времевото клеймо „%s“ не може да Ñе компилира " #, c-format msgid "regexec returned %d for input: %s" @@ -1126,11 +1157,11 @@ msgstr "кръпката е Ñ Ð¸Ð·Ñ†Ñло повредени данни на Ñ #, c-format msgid "unable to read symlink %s" -msgstr "Ñимволната връзка „%s“ не може да бъде прочетена" +msgstr "Ñимволната връзка „%s“ не може да Ñе прочете" #, c-format msgid "unable to open or read %s" -msgstr "файлът „%s“ не може да бъде отворен или прочетен" +msgstr "файлът „%s“ не може да Ñе отвори или прочете" #, c-format msgid "invalid start of line: '%c'" @@ -1183,12 +1214,11 @@ msgstr "кръпката ÑъответÑтва на „%s“, който Ñ‚Ñ€Ñ #, c-format msgid "the necessary postimage %s for '%s' cannot be read" msgstr "" -"необходимиÑÑ‚ резултат Ñлед операциÑта — „%s“ за „%s“ не може да бъде " -"прочетен" +"необходимиÑÑ‚ резултат Ñлед операциÑта — „%s“ за „%s“ не може да Ñе прочете" #, c-format msgid "binary patch does not apply to '%s'" -msgstr "двоичната кръпка не може да бъде приложена върху „%s“" +msgstr "двоичната кръпка не може да Ñе приложи върху „%s“" #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" @@ -1206,7 +1236,7 @@ msgstr "„%s“ не може да Ñе изтегли" #, c-format msgid "failed to read %s" -msgstr "файлът „%s“ не може да бъде прочетен" +msgstr "файлът „%s“ не може да Ñе прочете" #, c-format msgid "reading from '%s' beyond a symbolic link" @@ -1233,7 +1263,7 @@ msgstr "Тройно Ñливане…\n" #, c-format msgid "cannot read the current contents of '%s'" -msgstr "текущото Ñъдържание на „%s“ не може да бъде прочетено" +msgstr "текущото Ñъдържание на „%s“ не може да Ñе прочете" #, c-format msgid "Failed to perform three-way merge...\n" @@ -1289,7 +1319,7 @@ msgstr "заÑегнатиÑÑ‚ файл „%s“ е Ñлед Ñимволна в #, c-format msgid "%s: patch does not apply" -msgstr "Кръпката „%s“ не може да бъде приложена" +msgstr "Кръпката „%s“ не може да Ñе приложи" #, c-format msgid "Checking patch %s..." @@ -1369,7 +1399,7 @@ msgstr "Ñъкращаване на името на файла Ñ Ð¾Ñ‚Ñ…Ð²ÑŠÑ€Ð» #, c-format msgid "cannot open %s" -msgstr "„%s“ не може да бъде отворен" +msgstr "„%s“ не може да Ñе отвори" #, c-format msgid "cannot unlink '%s'" @@ -1392,11 +1422,11 @@ msgstr "" "Ðа входа нÑма непразни кръпки (те Ñе приемат при Ð¾Ð¿Ñ†Ð¸Ñ â€ž--allow-empty“)" msgid "unable to read index file" -msgstr "индекÑÑŠÑ‚ не може да бъде запиÑан" +msgstr "индекÑÑŠÑ‚ не може да Ñе запише" #, c-format msgid "can't open patch '%s': %s" -msgstr "кръпката „%s“ не може да бъде отворена: %s" +msgstr "кръпката „%s“ не може да Ñе отвори: %s" #, c-format msgid "squelched %d whitespace error" @@ -1419,7 +1449,7 @@ msgstr[1] "" "Добавени Ñа %d реда Ñлед корекциÑта на грешките в знаците за интервали." msgid "Unable to write new index file" -msgstr "ÐовиÑÑ‚ Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ може да бъде запиÑан" +msgstr "ÐовиÑÑ‚ Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ може да Ñе запише" msgid "don't apply changes matching the given path" msgstr "без прилагане на промѐните напаÑващи на Ð´Ð°Ð´ÐµÐ½Ð¸Ñ Ð¿ÑŠÑ‚" @@ -1449,7 +1479,7 @@ msgid "instead of applying the patch, see if the patch is applicable" msgstr "проверка дали кръпката може да Ñе приложи, без дейÑтвително прилагане" msgid "make sure the patch is applicable to the current index" -msgstr "проверка дали кръпката може да бъде приложена към Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑ" +msgstr "проверка дали кръпката може да Ñе приложи към Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑ" msgid "mark new files with `git add --intent-to-add`" msgstr "отбелÑзване на новите файлове Ñ â€žgit add --intent-to-add“" @@ -1462,8 +1492,7 @@ msgstr "прилагане на кръпка, коÑто Ð¿Ñ€Ð¾Ð¼ÐµÐ½Ñ Ð¸ фаРmsgid "also apply the patch (use with --stat/--summary/--check)" msgstr "" -"кръпката да бъде приложена. ОпциÑта Ñе комбинира Ñ â€ž--check“/„--stat“/„--" -"summary“" +"кръпката Ñе приложи. ОпциÑта Ñе комбинира Ñ â€ž--check“/„--stat“/„--summary“" msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "" @@ -1519,7 +1548,7 @@ msgstr "да не Ñе връща грешка при празни кръпки" #, c-format msgid "cannot stream blob %s" -msgstr "обектът-BLOB „%s“ не може да бъде обработен" +msgstr "обектът-BLOB „%s“ не може да Ñе обработи" #, c-format msgid "unsupported file mode: 0%o (SHA1: %s)" @@ -1531,10 +1560,10 @@ msgstr "грешка при декомпреÑиране Ñ â€ždeflate“ (%d)" #, c-format msgid "unable to start '%s' filter" -msgstr "филтърът „%s“ не може да бъде Ñтартиран" +msgstr "филтърът „%s“ не може да Ñе Ñтартира" msgid "unable to redirect descriptor" -msgstr "деÑкрипторът не може да бъде пренаÑочен" +msgstr "деÑкрипторът не може да Ñе пренаÑочи" #, c-format msgid "'%s' filter reported error" @@ -1566,7 +1595,7 @@ msgstr "git archive --remote ХРÐÐИЛИЩЕ [--exec КОМÐÐДÐ] --list" #, c-format msgid "cannot read '%s'" -msgstr "файлът „%s“ не може да бъде прочетен" +msgstr "файлът „%s“ не може да Ñе прочете" #, c-format msgid "pathspec '%s' matches files outside the current directory" @@ -1673,6 +1702,10 @@ msgid "Unexpected option --output" msgstr "Ðеочаквана Ð¾Ð¿Ñ†Ð¸Ñ â€ž--output“" #, c-format +msgid "extra command line parameter '%s'" +msgstr "излишна Ð¾Ð¿Ñ†Ð¸Ñ Ð¸Ð»Ð¸ ÑтойноÑÑ‚ на ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¸Ñ Ñ€ÐµÐ´: „%s“" + +#, c-format msgid "Unknown archive format '%s'" msgstr "Ðепознат формат на архив: „%s“" @@ -1720,6 +1753,14 @@ msgstr "" "„GIT_ATTR_SOURCE“" #, c-format +msgid "unable to stat '%s'" +msgstr "„stat“ не може да Ñе изпълни върху „%s“" + +#, c-format +msgid "unable to read %s" +msgstr "обектът „%s“ не може да бъде прочетен" + +#, c-format msgid "Badly quoted content in file '%s': %s" msgstr "Ðеправилно цитирано Ñъдържание във файла „%s“: %s" @@ -1771,7 +1812,7 @@ msgid "" "So we cannot be sure the first %s commit is between %s and %s.\n" "We continue anyway." msgstr "" -"базата за Ñливане между „%s“ и [%s] трÑбва да бъде преÑкочена.\n" +"базата за Ñливане между „%s“ и [%s] трÑбва да Ñе преÑкочи.\n" "Ðе може да Ñме Ñигурни, че първото %s подаване е между „%s“ и „%s“.\n" "Двоичното търÑене продължава." @@ -1785,11 +1826,11 @@ msgstr "необходима е верÑÐ¸Ñ â€ž%s“" #, c-format msgid "could not create file '%s'" -msgstr "файлът „%s“ не може да бъде Ñъздаден" +msgstr "файлът „%s“ не може да Ñе Ñъздаде" #, c-format msgid "could not read file '%s'" -msgstr "файлът „%s“ не може да бъде прочетен" +msgstr "файлът „%s“ не може да Ñе прочете" msgid "reading bisect refs failed" msgstr "неуÑпешно прочитане на указателите за двоично търÑене" @@ -1844,7 +1885,7 @@ msgstr "нÑма път на име „%s“ в „%s“" #, c-format msgid "cannot read blob %s for path %s" -msgstr "обектът-BLOB „%s“ в Ð¿ÑŠÑ‚Ñ %s не може да бъде прочетен" +msgstr "обектът-BLOB „%s“ в Ð¿ÑŠÑ‚Ñ %s не може да Ñе прочете" msgid "" "cannot inherit upstream tracking configuration of multiple refs when " @@ -1871,7 +1912,7 @@ msgid "branch '%s' set up to track:" msgstr "клонът „%s“ ще Ñледи:" msgid "unable to write upstream branch configuration" -msgstr "наÑтройките за ÑÐ»ÐµÐ´ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½ не може да бъдат запиÑани" +msgstr "наÑтройките за ÑÐ»ÐµÐ´ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½ не може да Ñе запишат" msgid "" "\n" @@ -1944,11 +1985,11 @@ msgstr "„%s“ не е позволено име за клон" msgid "a branch named '%s' already exists" msgstr "вече ÑъщеÑтвува клон Ñ Ð¸Ð¼Ðµ „%s“." -# FIXME #, c-format -msgid "cannot force update the branch '%s' checked out at '%s'" +msgid "cannot force update the branch '%s' used by worktree at '%s'" msgstr "" -"не може принудително да обновите клона „%s“, който е изтеглен в Ð¿ÑŠÑ‚Ñ â€ž%s“" +"не може принудително да обновите клона „%s“, който Ñе ползва от работното " +"дърво в „%s“" #, c-format msgid "cannot set up tracking information; starting point '%s' is not a branch" @@ -2007,8 +2048,8 @@ msgid "submodule '%s': cannot create branch '%s'" msgstr "подмодул „%s“: клонът „%s“ не може да Ñе Ñъздаде" #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "„%s“ вече е изтеглен в „%s“" +msgid "'%s' is already used by worktree at '%s'" +msgstr "„%s“ вече Ñе ползва от работното дърво в „%s“" msgid "git add [<options>] [--] <pathspec>..." msgstr "git add [ОПЦИЯ…] [--] ПЪТ…" @@ -2017,17 +2058,6 @@ msgstr "git add [ОПЦИЯ…] [--] ПЪТ…" msgid "cannot chmod %cx '%s'" msgstr "права̀та на „%2$s“ не може да Ñе зададат да Ñа %1$cx" -#, c-format -msgid "unexpected diff status %c" -msgstr "неочакван изходен код при генериране на разлика: %c" - -msgid "updating files failed" -msgstr "неуÑпешно обновÑване на файловете" - -#, c-format -msgid "remove '%s'\n" -msgstr "изтриване на „%s“\n" - msgid "Unstaged changes after refreshing the index:" msgstr "Промѐни, които и Ñлед обновÑването на индекÑа не Ñа добавени към него:" @@ -2038,29 +2068,26 @@ msgstr "" "ÐаÑтройката „add.interactive.useBuiltin“ е премахната!\n" "За подробноÑти Ñ Ð¿Ð¾Ñ‚ÑŠÑ€Ñете в изхода от „git help config“." -msgid "Could not read the index" -msgstr "ИндекÑÑŠÑ‚ не може да бъде прочетен" - -msgid "Could not write patch" -msgstr "Кръпката не може да бъде запиÑана" +msgid "could not read the index" +msgstr "индекÑÑŠÑ‚ не може да Ñе прочете" msgid "editing patch failed" msgstr "неуÑпешно редактиране на кръпка" #, c-format -msgid "Could not stat '%s'" -msgstr "Ðе може да Ñе получи Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ñ‡Ñ€ÐµÐ· „stat“ за файла „%s“" +msgid "could not stat '%s'" +msgstr "неуÑпешно изпълнение на „stat“ върху „%s“" -msgid "Empty patch. Aborted." -msgstr "Празна кръпка, преуÑтановÑване на дейÑтвието." +msgid "empty patch. aborted" +msgstr "празна кръпка, преуÑтановÑване на дейÑтвието" #, c-format -msgid "Could not apply '%s'" -msgstr "Кръпката „%s“ не може да бъде приложена" +msgid "could not apply '%s'" +msgstr "кръпката „%s“ не може да Ñе приложи" msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" -"Следните пътища ще бъдат игнорирани Ñпоред нÑкой от файловете „.gitignore“:\n" +"Следните пътища ще Ñе игнорират Ñпоред нÑкой от файловете „.gitignore“:\n" msgid "dry run" msgstr "пробно изпълнение" @@ -2087,7 +2114,7 @@ msgid "renormalize EOL of tracked files (implies -u)" msgstr "уеднаквÑване на знаците за край на файл (включва опциÑта „-u“)" msgid "record only the fact that the path will be added later" -msgstr "отбелÑзване Ñамо на факта, че пътÑÑ‚ ще бъде добавен по-къÑно" +msgstr "отбелÑзване Ñамо на факта, че пътÑÑ‚ ще Ñе добави по-къÑно" msgid "add changes from all tracked and untracked files" msgstr "добавÑне на вÑички промѐни в Ñледените и неÑледените файлове" @@ -2101,7 +2128,7 @@ msgid "don't add, only refresh the index" msgstr "без добавÑне на нови файлове, Ñамо обновÑване на индекÑа" msgid "just skip files which cannot be added because of errors" -msgstr "преÑкачане на файловете, които не може да бъдат добавени поради грешки" +msgstr "преÑкачане на файловете, които не може да Ñе добавÑÑ‚ поради грешки" msgid "check if - even missing - files are ignored in dry run" msgstr "" @@ -2190,6 +2217,9 @@ msgstr "" msgid "index file corrupt" msgstr "файлът Ñ Ð¸Ð½Ð´ÐµÐºÑа е повреден" +msgid "unable to write new index file" +msgstr "неуÑпешно запиÑване на Ð½Ð¾Ð²Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑ" + #, c-format msgid "bad action '%s' for '%s'" msgstr "неправилно дейÑтвие „%s“ за „%s“" @@ -2200,7 +2230,7 @@ msgstr "неправилна ÑтойноÑÑ‚ за „%s“: „%s“" #, c-format msgid "could not read '%s'" -msgstr "файлът „%s“ не може да бъде прочетен" +msgstr "файлът „%s“ не може да Ñе прочете" msgid "could not parse author script" msgstr "Ñкриптът за автор не може да Ñе анализира" @@ -2226,11 +2256,11 @@ msgstr "неуÑпешно изпълнение на „fseek“" #, c-format msgid "could not open '%s' for reading" -msgstr "файлът не може да бъде прочетен: „%s“" +msgstr "файлът не може да Ñе прочете: „%s“" #, c-format msgid "could not open '%s' for writing" -msgstr "„%s“ не може да бъде отворен за запиÑ" +msgstr "„%s“ не може да Ñе отвори за запиÑ" #, c-format msgid "could not parse patch '%s'" @@ -2238,7 +2268,7 @@ msgstr "кръпката „%s“ не може да Ñе анализира" msgid "Only one StGIT patch series can be applied at once" msgstr "" -"Само една поредица от кръпки от „StGIT“ може да бъде прилагана в даден момент" +"Само една поредица от кръпки от „StGIT“ може да Ñе приложи в даден момент" msgid "invalid timestamp" msgstr "неправилна ÑтойноÑÑ‚ за времево клеймо" @@ -2250,14 +2280,14 @@ msgid "invalid timezone offset" msgstr "неправилно отмеÑтване на чаÑÐ¾Ð²Ð¸Ñ Ð¿Ð¾ÑÑ" msgid "Patch format detection failed." -msgstr "Форматът на кръпката не може да бъде определен." +msgstr "Форматът на кръпката не може да Ñе определи." #, c-format msgid "failed to create directory '%s'" -msgstr "директориÑта „%s“ не може да бъде Ñъздадена" +msgstr "директориÑта „%s“ не може да Ñе Ñъздаде" msgid "Failed to split patches." -msgstr "Кръпките не може да бъдат разделени." +msgstr "Кръпките не може да Ñе разделÑÑ‚." #, c-format msgid "When you have resolved this problem, run \"%s --continue\"." @@ -2302,7 +2332,7 @@ msgstr "грешен ред Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‡Ð½Ð¾ÑÑ‚: %.*s" #, c-format msgid "unable to parse commit %s" -msgstr "подаването не може да бъде анализирано: %s" +msgstr "подаването не може да Ñе анализира: %s" msgid "Repository lacks necessary blobs to fall back on 3-way merge." msgstr "" @@ -2332,7 +2362,7 @@ msgid "applying to an empty history" msgstr "прилагане върху празна иÑториÑ" msgid "failed to write commit object" -msgstr "обектът за подаването не може да бъде запиÑан" +msgstr "обектът за подаването не може да Ñе запише" #, c-format msgid "cannot resume: %s does not exist." @@ -2352,12 +2382,11 @@ msgstr "" "на вÑичко:" msgid "unable to write index file" -msgstr "индекÑÑŠÑ‚ не може да бъде запиÑан" +msgstr "индекÑÑŠÑ‚ не може да Ñе запише" #, c-format msgid "Dirty index: cannot apply patches (dirty: %s)" -msgstr "" -"ИндекÑÑŠÑ‚ не е чиÑÑ‚: кръпките не може да бъдат приложени (замърÑени Ñа: %s)" +msgstr "ИндекÑÑŠÑ‚ не е чиÑÑ‚: кръпките не може да Ñе приложат (замърÑени Ñа: %s)" #, c-format msgid "Skipping: %.*s" @@ -2409,15 +2438,12 @@ msgstr "" "След ÐºÐ¾Ñ€ÐµÐºÑ†Ð¸Ñ Ð½Ð° конфликтите изпълнете „git add“ върху поправените файлове.\n" "За да приемете „изтрити от Ñ‚Ñх“, изпълнете „git rm“ върху изтритите файлове." -msgid "unable to write new index file" -msgstr "неуÑпешно запиÑване на Ð½Ð¾Ð²Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑ" - #, c-format msgid "Could not parse object '%s'." msgstr "„%s“ не е разпознат като обект." msgid "failed to clean index" -msgstr "индекÑÑŠÑ‚ не може да бъде изчиÑтен" +msgstr "индекÑÑŠÑ‚ не може да Ñе изчиÑти" msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" @@ -2431,17 +2457,13 @@ msgstr "" #, c-format msgid "failed to read '%s'" -msgstr "„%s“ не може да бъде прочетен" - -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "опциите „%s=%s“ и „%s=%s“ Ñа неÑъвмеÑтими" +msgstr "„%s“ не може да Ñе прочете" msgid "git am [<options>] [(<mbox> | <Maildir>)...]" -msgstr "git am [ОПЦИЯ…] [(ФÐЙЛ_С_ПОЩР| ДИРЕКТОРИЯ_С_ПОЩÐ)…]" +msgstr "git am [ОПЦИЯ…] [(ФÐЙЛ_С_ПОЩÐ|ДИРЕКТОРИЯ_С_ПОЩÐ)…]" msgid "git am [<options>] (--continue | --skip | --abort)" -msgstr "git am [ОПЦИЯ…] (--continue | --skip | --abort)" +msgstr "git am [ОПЦИЯ…] (--continue|--skip|--abort)" msgid "run interactively" msgstr "интерактивна работа" @@ -2479,11 +2501,6 @@ msgid "pass --keep-cr flag to git-mailsplit for mbox format" msgstr "" "подаване на опциÑта „--keep-cr“ на командата „git-mailsplit“ за формат „mbox“" -msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" -msgstr "" -"без подаване на опциÑта „--keep-cr“ на командата „git-mailsplit“ незавиÑимо " -"от „am.keepcr“" - msgid "strip everything before a scissors line" msgstr "пропуÑкане на вÑичко преди реда за отрÑзване" @@ -2581,7 +2598,7 @@ msgid "git apply [<options>] [<patch>...]" msgstr "git apply [ОПЦИЯ…] [КРЪПКÐ…]" msgid "could not redirect output" -msgstr "изходът не може да бъде пренаÑочен" +msgstr "изходът не може да Ñе пренаÑочи" msgid "git archive: Remote with no URL" msgstr "git archive: ЛипÑва Ð°Ð´Ñ€ÐµÑ Ð·Ð° отдалеченото хранилище" @@ -2601,12 +2618,12 @@ msgid "git archive: expected a flush" msgstr "git archive: очакваше Ñе изчиÑтване на буферите чрез „flush“" msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=УПРÐВЛЯВÐЩÐ_ДУМР--term-{old,good}" -"=УПРÐВЛЯВÐЩÐ_ДУМÐ] [--no-checkout] [--first-parent] [ЛОШО [ДОБРО…]] [--] " -"[ПЪТ…]" +"git bisect start [--term-(new,bad)=УПРÐВЛЯВÐЩÐ_ДУМР--term-(old," +"good)=УПРÐВЛЯВÐЩÐ_ДУМÐ] [--no-checkout] [--first-parent] [ЛОШО [ДОБРО…]] " +"[--] [ПЪТ…]" msgid "git bisect (good|bad) [<rev>...]" msgstr "git bisect (good|bad) [ВЕРСИЯ…]" @@ -2620,8 +2637,8 @@ msgstr "git bisect reset [ПОДÐÐ’ÐÐЕ]" msgid "git bisect replay <logfile>" msgstr "git bisect replay ИМЕ_ÐÐ_ФÐЙЛ" -msgid "git bisect run <cmd>..." -msgstr "git bisect run КОМÐÐДÐ…" +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run КОМÐÐДÐ… [ÐРГУМЕÐТ…]" #, c-format msgid "cannot open file '%s' in mode '%s'" @@ -2633,7 +2650,7 @@ msgstr "във файла „%s“ не може да Ñе пише" #, c-format msgid "cannot open file '%s' for reading" -msgstr "файлът „%s“ не може да бъде отворен за четене" +msgstr "файлът „%s“ не може да Ñе отвори за четене" #, c-format msgid "'%s' is not a valid term" @@ -2662,8 +2679,8 @@ msgstr "„%s“ не е подаване" msgid "" "could not check out original HEAD '%s'. Try 'git bisect reset <commit>'." msgstr "" -"първоначално указаното „%s“ в ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ â€žHEAD“ не може да бъде\n" -"изтеглено. Пробвайте да изпълните командата „git bisect reset ПОДÐÐ’ÐÐЕ“." +"първоначално указаното „%s“ в ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ â€žHEAD“ не може да Ñе\n" +"изтегли. Пробвайте да изпълните командата „git bisect reset ПОДÐÐ’ÐÐЕ“." #, c-format msgid "Bad bisect_write argument: %s" @@ -3034,7 +3051,7 @@ msgid "Blaming lines" msgstr "Редове Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ñтво" msgid "git branch [<options>] [-r | -a] [--merged] [--no-merged]" -msgstr "git branch [ОПЦИЯ…] [-r | -a] [--merged] [--no-merged]" +msgstr "git branch [ОПЦИЯ…] [-r|-a] [--merged] [--no-merged]" msgid "" "git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-" @@ -3045,61 +3062,65 @@ msgid "git branch [<options>] [-l] [<pattern>...]" msgstr "git branch [ОПЦИЯ…] [-l] [ШÐБЛОÐ…]" msgid "git branch [<options>] [-r] (-d | -D) <branch-name>..." -msgstr "git branch [ОПЦИЯ…] [-r] (-d | -D) ИМЕ_ÐÐ_КЛОÐ…" +msgstr "git branch [ОПЦИЯ…] [-r] (-d|-D) ИМЕ_ÐÐ_КЛОÐ…" msgid "git branch [<options>] (-m | -M) [<old-branch>] <new-branch>" -msgstr "git branch [ОПЦИЯ…] (-m | -M) [СТÐÐ _КЛОÐ] ÐОВ_КЛОÐ" +msgstr "git branch [ОПЦИЯ…] (-m|-M) [СТÐÐ _КЛОÐ] ÐОВ_КЛОÐ" msgid "git branch [<options>] (-c | -C) [<old-branch>] <new-branch>" -msgstr "git branch [ОПЦИЯ…] (-c | -C) [СТÐÐ _КЛОÐ] ÐОВ_КЛОÐ" +msgstr "git branch [ОПЦИЯ…] (-c|-C) [СТÐÐ _КЛОÐ] ÐОВ_КЛОÐ" msgid "git branch [<options>] [-r | -a] [--points-at]" -msgstr "git branch [ОПЦИЯ…] [-r | -a] [--points-at]" +msgstr "git branch [ОПЦИЯ…] [-r|-a] [--points-at]" msgid "git branch [<options>] [-r | -a] [--format]" -msgstr "git branch [ОПЦИЯ…] [-r | -a] [--format]" +msgstr "git branch [ОПЦИЯ…] [-r|-a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" "изтриване на клона „%s“, който е ÑлÑÑ‚ към „%s“,\n" -" но още не е ÑлÑÑ‚ към върха „HEAD“." +" но още не е ÑлÑÑ‚ към върха „HEAD“" #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" "отказване на изтриване на клона „%s“, който не е ÑлÑÑ‚ към\n" -" „%s“, но е ÑлÑÑ‚ към върха „HEAD“." +" „%s“, но е ÑлÑÑ‚ към върха „HEAD“" #, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "Обектът-подаване за „%s“ не може да бъде открит" +msgid "couldn't look up commit object for '%s'" +msgstr "обектът-подаване за „%s“ не може да Ñе открие" #, 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'." +msgid "the branch '%s' is not fully merged" +msgstr "клонът „%s“ не е ÑлÑÑ‚ напълно" + +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" msgstr "" -"Клонът „%s“ не е ÑлÑÑ‚ напълно. Ðко Ñте Ñигурни, че иÑкате\n" -"да го изтриете, изпълнете „git branch -D %s“." +"Ðко Ñте Ñигурни, че иÑкате да го изтриете, изпълнете:\n" +"\n" +" git branch -D %s" -msgid "Update of config-file failed" -msgstr "ÐеуÑпешно обновÑване на ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»" +msgid "update of config-file failed" +msgstr "неуÑпешно обновÑване на ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»" msgid "cannot use -a with -d" msgstr "опциите „-a“ и „-d“ Ñа неÑъвмеÑтими" #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "Ðе може да изтриете клона „%s“, който е изтеглен в Ð¿ÑŠÑ‚Ñ â€ž%s“" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "" +"не може да изтриете клона „%s“, който Ñе ползва от работното дърво в „%s“" #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "ÑледÑщиÑÑ‚ клон „%s“ не може да бъде открит." +msgid "remote-tracking branch '%s' not found" +msgstr "ÑледÑщиÑÑ‚ клон „%s“ липÑва" #, c-format msgid "" @@ -3110,8 +3131,8 @@ msgstr "" "Пробвахте ли опциÑта „--remote“?" #, c-format -msgid "branch '%s' not found." -msgstr "клонът „%s“ не може да бъде открит." +msgid "branch '%s' not found" +msgstr "клонът „%s“ липÑва" #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" @@ -3129,55 +3150,55 @@ msgstr "подаването, Ñочено от ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ â€žHEAD“, Ð #, c-format msgid "HEAD (%s) points outside of refs/heads/" -msgstr "„HEAD“ (%s) Ñочи извън директориÑта „refs/heads“" +msgstr "„HEAD“ (%s) Ñочи извън директориÑта „refs/heads/“" #, c-format -msgid "Branch %s is being rebased at %s" -msgstr "Клонът „%s“ Ñе пребазира върху „%s“" +msgid "branch %s is being rebased at %s" +msgstr "клонът „%s“ Ñе пребазира върху „%s“" #, c-format -msgid "Branch %s is being bisected at %s" -msgstr "ТърÑи Ñе двоично в клона „%s“ при „%s“" +msgid "branch %s is being bisected at %s" +msgstr "търÑи Ñе двоично в клона „%s“ при „%s“" #, c-format msgid "HEAD of working tree %s is not updated" msgstr "УказателÑÑ‚ „HEAD“ на работното дърво „%s“ не е обновен" #, c-format -msgid "Invalid branch name: '%s'" -msgstr "Ðеправилно име на клон: „%s“" +msgid "invalid branch name: '%s'" +msgstr "неправилно име на клон: „%s“" #, c-format -msgid "No commit on branch '%s' yet." -msgstr "Ð’ клона „%s“ вÑе още нÑма подаваниÑ." +msgid "no commit on branch '%s' yet" +msgstr "в клона „%s“ вÑе още нÑма подаваниÑ" #, c-format -msgid "No branch named '%s'." -msgstr "ЛипÑва клон на име „%s“." +msgid "no branch named '%s'" +msgstr "липÑва клон на име „%s“" -msgid "Branch rename failed" -msgstr "ÐеуÑпешно преименуване на клон" +msgid "branch rename failed" +msgstr "неуÑпешно преименуване на клон" -msgid "Branch copy failed" -msgstr "ÐеуÑпешно копиране на клон" +msgid "branch copy failed" +msgstr "неуÑпешно копиране на клон" #, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "Клонът Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»Ð½Ð¾ име „%s“ е копиран" +msgid "created a copy of a misnamed branch '%s'" +msgstr "клонът Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»Ð½Ð¾ име „%s“ е копиран" #, c-format -msgid "Renamed a misnamed branch '%s' away" -msgstr "Клонът Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»Ð½Ð¾ име „%s“ е преименуван" +msgid "renamed a misnamed branch '%s' away" +msgstr "клонът Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»Ð½Ð¾ име „%s“ е преименуван" #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "Клонът е преименуван на „%s“, но указателÑÑ‚ „HEAD“ не е обновен" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "клонът е преименуван на „%s“, но указателÑÑ‚ „HEAD“ не е обновен" -msgid "Branch is renamed, but update of config-file failed" -msgstr "Клонът е преименуван, но конфигурационниÑÑ‚ файл не е обновен" +msgid "branch is renamed, but update of config-file failed" +msgstr "клонът е преименуван, но конфигурационниÑÑ‚ файл не е обновен" -msgid "Branch is copied, but update of config-file failed" -msgstr "Клонът е копиран, но конфигурационниÑÑ‚ файл не е обновен" +msgid "branch is copied, but update of config-file failed" +msgstr "клонът е копиран, но конфигурационниÑÑ‚ файл не е обновен" #, c-format msgid "" @@ -3294,8 +3315,8 @@ msgstr "рекурÑивно обхождане подмодулите" msgid "format to use for the output" msgstr "ФОРМÐТ за изхода" -msgid "Failed to resolve HEAD as a valid ref." -msgstr "Ðе може да Ñе открие към какво Ñочи указателÑÑ‚ „HEAD“" +msgid "failed to resolve HEAD as a valid ref" +msgstr "указателÑÑ‚ „HEAD“ не Ñочи към обект" msgid "HEAD not found below refs/heads!" msgstr "Ð’ директориÑта „refs/heads“ липÑва файл „HEAD“" @@ -3314,16 +3335,16 @@ msgstr "" msgid "branch name required" msgstr "Ðеобходимо е име на клон" -msgid "Cannot give description to detached HEAD" -msgstr "Ðе може да зададете опиÑание на неÑвързан „HEAD“" +msgid "cannot give description to detached HEAD" +msgstr "не може да зададете опиÑание на неÑвързан „HEAD“" msgid "cannot edit description of more than one branch" -msgstr "Ðе може да редактирате опиÑанието на повече от един клон едновременно" +msgstr "не може да редактирате опиÑанието на повече от един клон едновременно" -msgid "cannot copy the current branch while not on any." +msgid "cannot copy the current branch while not on any" msgstr "не може да копирате Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ ÐºÐ»Ð¾Ð½, защото Ñте извън който и да е клон" -msgid "cannot rename the current branch while not on any." +msgid "cannot rename the current branch while not on any" msgstr "" "не може да преименувате Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ ÐºÐ»Ð¾Ð½, защото Ñте извън който и да е клон" @@ -3338,32 +3359,31 @@ msgstr "прекалено много аргументи към командат #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." +"could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" -"Следеното от „HEAD“ не може да Ñе зададе да е „%s“, защото то не Ñочи към " -"никой клон." +"Ñледеното от „HEAD“ не може да Ñе зададе да е „%s“, защото то не Ñочи към " +"никой клон" #, c-format msgid "no such branch '%s'" -msgstr "ÐÑма клон на име „%s“." +msgstr "нÑма клон на име „%s“." #, c-format msgid "branch '%s' does not exist" -msgstr "Ðе ÑъщеÑтвува клон на име „%s“." +msgstr "не ÑъщеÑтвува клон на име „%s“." msgid "too many arguments to unset upstream" msgstr "прекалено много аргументи към командата за Ñпиране на Ñледене" -msgid "could not unset upstream of HEAD when it does not point to any branch." -msgstr "" -"Следеното от „HEAD“ не може да махне, защото то не Ñочи към никой клон." +msgid "could not unset upstream of HEAD when it does not point to any branch" +msgstr "Ñледеното от „HEAD“ не може да махне, защото то не Ñочи към никой клон" #, c-format -msgid "Branch '%s' has no upstream information" -msgstr "ÐÑма Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ ÐºÐ»Ð¾Ð½ÑŠÑ‚ „%s“ да Ñледи нÑкой друг" +msgid "branch '%s' has no upstream information" +msgstr "нÑма Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ ÐºÐ»Ð¾Ð½ÑŠÑ‚ „%s“ да Ñледи нÑкой друг" msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"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 "" "опциите „-a“ и „-r“ на „git branch“ Ñа неÑъвмеÑтими Ñ Ð¸Ð¼Ðµ на клон.\n" @@ -3371,7 +3391,7 @@ msgstr "" msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." +"'--set-upstream-to' instead" msgstr "" "опциÑта „--set-upstream“ вече не Ñе поддържа. Използвайте „--track“ или „--" "set-upstream-to“" @@ -3396,7 +3416,7 @@ msgid "" "git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n" " [--diagnose[=<mode>]]" msgstr "" -"git bugreport [(-o | --output-directory) ПЪТ] [(-s | --suffix) ФОРМÐТ]\n" +"git bugreport [(-o|--output-directory) ПЪТ] [(-s|--suffix) ФОРМÐТ]\n" " [--diagnose[=РЕЖИМ]]" msgid "" @@ -3450,6 +3470,10 @@ msgid "specify a strftime format suffix for the filename(s)" msgstr "укажете ÑуфикÑа на файловете във формат за „strftime“" #, c-format +msgid "unknown argument `%s'" +msgstr "непозната Ð¾Ð¿Ñ†Ð¸Ñ â€ž%s“" + +#, c-format msgid "could not create leading directories for '%s'" msgstr "родителÑките директории на „%s“ не може да бъдат Ñъздадени" @@ -3475,11 +3499,11 @@ msgid "" "git bundle create [-q | --quiet | --progress]\n" " [--version=<version>] <file> <git-rev-list-args>" msgstr "" -"git bundle create [-q | --quiet | --progress ]\n" +"git bundle create [-q|--quiet|--progress ]\n" " [--version=ВЕРСИЯ] ФÐЙЛ ОПЦИЯ_ЗÐ_git-rev-list…" msgid "git bundle verify [-q | --quiet] <file>" -msgstr "git bundle verify [-q | --quiet] ФÐЙЛ" +msgstr "git bundle verify [-q|--quiet] ФÐЙЛ" msgid "git bundle list-heads <file> [<refname>...]" msgstr "git bundle list-heads ФÐЙЛ [ИМЕ_ÐÐ_УКÐЗÐТЕЛ…]" @@ -3550,28 +3574,27 @@ msgid "git cat-file <type> <object>" msgstr "git cat-file ВИД ОБЕКТ" msgid "git cat-file (-e | -p) <object>" -msgstr "git cat-file (-e | -p) ОБЕКТ" +msgstr "git cat-file (-e|-p) ОБЕКТ" msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" -msgstr "git cat-file (-t | -s) [--allow-unknown-type] ОБЕКТ" +msgstr "git cat-file (-t|-s) [--allow-unknown-type] ОБЕКТ" msgid "" -"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" -"objects]\n" -" [--buffer] [--follow-symlinks] [--unordered]\n" -" [--textconv | --filters] [-z]" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" msgstr "" +"git cat-file (--textconv|--filters)\n" +" [ВЕРСИЯ:ПЪТ|ДЪРВО|--path=ПЪТ|ДЪРВО ВЕРСИЯ]" + +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" -" [--textconv | --filters] [-z]" - -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +" [--textconv | --filters] [-Z]" msgstr "" -"git cat-file (--textconv | --filters)\n" -" [ВЕРСИЯ:ПЪТ|ДЪРВО | --path=ПЪТ|ДЪРВО ВЕРСИЯ]" +"git cat-file (--batch|--batch-check|--batch-command) [--batch-all-objects]\n" +" [--buffer] [--follow-symlinks] [--unordered]\n" +" [--textconv|--filters] [-Z]" msgid "Check object existence or emit object contents" msgstr "Проверка за ÑъщеÑтвуването на обекта или извеждане на Ñъдържанието му" @@ -3615,6 +3638,9 @@ msgstr "като „--batch“, но без извеждане на Ñъдърж msgid "stdin is NUL-terminated" msgstr "ÑтандартниÑÑ‚ вход да ползва Ð½ÑƒÐ»ÐµÐ²Ð¸Ñ Ð·Ð½Ð°Ðº „NUL“ за разделител" +msgid "stdin and stdout is NUL-terminated" +msgstr "Ñтандартните вход и изход да ползват Ð½ÑƒÐ»ÐµÐ²Ð¸Ñ Ð·Ð½Ð°Ðº „NUL“ за разделител" + msgid "read commands from stdin" msgstr "изчитане на командите от ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð²Ñ…Ð¾Ð´" @@ -3689,14 +3715,12 @@ msgid "" "git check-attr [--source <tree-ish>] [-a | --all | <attr>...] [--] " "<pathname>..." msgstr "" -"git check-attr [--source УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [-a | --all | ÐТРИБУТ…] [--] " -"ПЪТ…" +"git check-attr [--source УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [-a|--all|ÐТРИБУТ…] [--] ПЪТ…" msgid "" "git check-attr --stdin [-z] [--source <tree-ish>] [-a | --all | <attr>...]" msgstr "" -"git check-attr --stdin [-z] [--source УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [-a | --all | " -"ÐТРИБУТ…]" +"git check-attr --stdin [-z] [--source УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [-a|--all|ÐТРИБУТ…]" msgid "report all attributes set on file" msgstr "извеждане на вÑички атрибути, зададени върху файл" @@ -3876,6 +3900,10 @@ msgid "'%s' or '%s' cannot be used with %s" msgstr "опциÑта „%3$s“ е неÑъвмеÑтима както Ñ â€ž%1$s“, така и Ñ â€ž%2$s“" #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "„%s“, „%s“ и „%s“ Ñа неÑъвмеÑтими Ñ Ð¸Ð·Ñ‚ÐµÐ³Ð»Ñнето на дърво" + +#, c-format msgid "path '%s' is unmerged" msgstr "пътÑÑ‚ „%s“ не е ÑлÑÑ‚" @@ -4134,8 +4162,8 @@ msgstr "принудително изтеглÑне (вашите промѐн msgid "new-branch" msgstr "ÐОВ_КЛОÐ" -msgid "new unparented branch" -msgstr "нов клон без родител" +msgid "new unborn branch" +msgstr "нов неродѐн клон" msgid "update ignored files (default)" msgstr "обновÑване на игнорираните файлове (Ñтандартно)" @@ -4165,7 +4193,7 @@ msgstr "липÑва име на клон, използвайте опциÑта #, c-format msgid "could not resolve %s" -msgstr "„%s“ не може да бъде открит" +msgstr "„%s“ не може да бъде проÑледен" msgid "invalid path specification" msgstr "указан е неправилен път" @@ -4240,7 +4268,7 @@ msgstr "използване на припокриващ режим" msgid "" "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] " "[<pathspec>...]" -msgstr "git clean [-d] [-f] [-i] [-n] [-q] [-e ШÐБЛОÐ] [-x | -X] [--] [ПЪТ…]" +msgstr "git clean [-d] [-f] [-i] [-n] [-q] [-e ШÐБЛОÐ] [-x|-X] [--] [ПЪТ…]" #, c-format msgid "Removing %s\n" @@ -4388,9 +4416,6 @@ msgstr "" "което изиÑква нÑÐºÐ¾Ñ Ð¾Ñ‚ опциите „-i“, „-n“ или „-f“. ÐÑма да Ñе извърши " "изчиÑтване" -msgid "-x and -X cannot be used together" -msgstr "опциите „-x“ и „-X“ Ñа неÑъвмеÑтими" - msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [ОПЦИЯ…] [--] ХРÐÐИЛИЩЕ [ДИРЕКТОРИЯ]" @@ -4482,6 +4507,9 @@ msgstr "СЛУЖЕБÐÐ_ДИРЕКТОРИЯ" msgid "separate git dir from working tree" msgstr "отделна СЛУЖЕБÐÐ_ДИРЕКТОРИЯ за git извън работното дърво" +msgid "specify the reference format to use" +msgstr "указване на форма̀та за указател" + msgid "key=value" msgstr "КЛЮЧ=СТОЙÐОСТ" @@ -4494,12 +4522,6 @@ msgstr "Ñпецифични за Ñървъра" msgid "option to transmit" msgstr "Ð¾Ð¿Ñ†Ð¸Ñ Ð·Ð° преноÑ" -msgid "use IPv4 addresses only" -msgstr "Ñамо адреÑи IPv4" - -msgid "use IPv6 addresses only" -msgstr "Ñамо адреÑи IPv6" - msgid "apply partial clone filters to submodules" msgstr "прилагане на филтрите за непълно хранилище към подмодулите" @@ -4615,12 +4637,9 @@ msgstr "Прекалено много аргументи." msgid "You must specify a repository to clone." msgstr "ТрÑбва да укажете кое хранилище иÑкате да клонирате." -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "" -"опциÑта „--bundle-uri“ е неÑъвмеÑтима Ñ â€ž--depth“, „--shallow-since“ и „--" -"shallow-exclude“" +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "непознат формат на Ñъхранение: „%s“" #, c-format msgid "repository '%s' does not exist" @@ -4758,11 +4777,11 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir ДИРЕКТОРИЯ] [--append]\n" -" [--split[=СТРÐТЕГИЯ]] [--reachable | --stdin-packs | " -"--stdin-commits]\n" +" [--split[=СТРÐТЕГИЯ]] [--reachable|--stdin-packs|--" +"stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters БРОЙ] [--" "[no-]progress]\n" " ОПЦИИ_ЗÐ_Ð ÐЗДЕЛЯÐЕ" @@ -4775,13 +4794,17 @@ msgstr "ДИРекториÑта_Ñ_ОБЕКТИ за запазване на г msgid "if the commit-graph is split, only verify the tip file" msgstr "" -"ако гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е раздробен, да Ñе проверÑва Ñамо файлът на върха" +"ако графът Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е раздробен, да Ñе проверÑва Ñамо файлът на върха" #, c-format msgid "Could not open commit-graph '%s'" msgstr "Графът Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта не може да Ñе отвори: „%s“" #, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "веригата на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта не може да Ñе отвори: „%s“" + +#, c-format msgid "unrecognized --split argument, %s" msgstr "непознат аргумент към „--split“: %s" @@ -4900,13 +4923,13 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u РЕЖИМ] [--amend]\n" -" [--dry-run] [(-c | -C | --squash) ПОДÐÐ’ÐÐЕ | --fixup [(amend|" +"git commit [-a|--interactive|--patch] [-s] [-v] [-u РЕЖИМ] [--amend]\n" +" [--dry-run] [(-c|-C|--squash) ПОДÐÐ’ÐÐЕ |--fixup [(amend|" "reword):]ПОДÐÐ’ÐÐЕ)]\n" -" [-F ФÐЙЛ | -m СЪОБЩЕÐИЕ] [--reset-author] [--allow-empty]\n" +" [-F ФÐЙЛ|-m СЪОБЩЕÐИЕ] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=ÐВТОР]\n" " [--date=ДÐТÐ] [--cleanup=РЕЖИМ] [--[no-]status]\n" -" [-i | -o] [--pathspec-from-file=ФÐЙЛ> [--pathspec-file-nul]]\n" +" [-i|-o] [--pathspec-from-file=ФÐЙЛ> [--pathspec-file-nul]]\n" " [(--trailer ЛЕКСЕМÐ[(=|:)СТОЙÐОСТ])…] [-" "S[ИДЕÐТИФИКÐТОР_ÐÐ_КЛЮЧ]]\n" " [--] [ПЪТ…]" @@ -4972,6 +4995,9 @@ msgstr "" " git cherry-pick --skip\n" "\n" +msgid "updating files failed" +msgstr "неуÑпешно обновÑване на файловете" + msgid "failed to unpack HEAD tree object" msgstr "върховото дърво (HEAD tree object) не може да бъде извадено от пакет" @@ -4990,9 +5016,6 @@ msgstr "временниÑÑ‚ Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ може да бъде обнов msgid "Failed to update main cache tree" msgstr "Кешът за обектите-дървета не може да бъде обновен" -msgid "unable to write new_index file" -msgstr "новиÑÑ‚ Ð¸Ð½Ð´ÐµÐºÑ (new_index) не може да бъде запиÑан" - msgid "cannot do a partial commit during a merge." msgstr "по време на Ñливане не може да Ñе извърши чаÑтично подаване." @@ -5031,7 +5054,7 @@ msgstr "" "използвани вÑички подобни знаци" #, c-format -msgid "could not lookup commit %s" +msgid "could not lookup commit '%s'" msgstr "Ñледното подаване не може да бъде открито: %s" #, c-format @@ -5404,12 +5427,12 @@ msgstr "Ðеизвършване на подаване поради празно msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" -"хранилището е обновено, но новиÑÑ‚ файл за Ð¸Ð½Ð´ÐµÐºÑ â€žnew_index“\n" -"не е запиÑан. Проверете дали диÑкът не е препълнен или не Ñте\n" -"превишили диÑковата Ñи квота. За възÑтановÑване изпълнете:\n" +"хранилището е обновено, но новиÑÑ‚ файл за Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ е запиÑан.\n" +"Проверете дали диÑкът не е препълнен или не Ñте превишили\n" +"диÑковата Ñи квота. За възÑтановÑване изпълнете:\n" "\n" " git restore --staged :/" @@ -5857,7 +5880,7 @@ msgid "" "git diagnose [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n" " [--mode=<mode>]" msgstr "" -"git diagnose [(-o | --output-directory) ПЪТ] [(-s | --suffix) ФОРМÐТ]\n" +"git diagnose [(-o|--output-directory) ПЪТ] [(-s|--suffix) ФОРМÐТ]\n" " [--diagnose[=РЕЖИМ]]" msgid "specify a destination for the diagnostics archive" @@ -6100,7 +6123,7 @@ msgid "git fetch [<options>] <group>" msgstr "git fetch [ОПЦИЯ…] ГРУПÐ" msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]" -msgstr "git fetch --multiple [ОПЦИЯ…] [(ХРÐÐИЛИЩЕ | ГРУПÐ)…]" +msgstr "git fetch --multiple [ОПЦИЯ…] [(ХРÐÐИЛИЩЕ|ГРУПÐ)…]" msgid "git fetch --all [<options>]" msgstr "git fetch --all [ОПЦИЯ…]" @@ -6442,8 +6465,7 @@ msgstr "опциÑта „--stdin“ поддържа доÑтавÑне ÑамРmsgid "" "git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]" -msgstr "" -"git fmt-merge-msg [-m СЪОБЩЕÐИЕ] [--log[=БРОЙ] | --no-log] [--file ФÐЙЛ]" +msgstr "git fmt-merge-msg [-m СЪОБЩЕÐИЕ] [--log[=БРОЙ]|--no-log] [--file ФÐЙЛ]" msgid "populate log with at most <n> entries from shortlog" msgstr "" @@ -6676,7 +6698,7 @@ msgstr "%s: неÑвързаниÑÑ‚ връх „HEAD“ не Ñочи към н #, c-format msgid "notice: %s points to an unborn branch (%s)" -msgstr "предупреждение: „%s“ Ñочи към вÑе още неÑъщеÑтвуващ клон (%s)" +msgstr "предупреждение: „%s“ Ñочи към неродѐн клон (%s)" #, c-format msgid "Checking cache tree of %s" @@ -6888,6 +6910,9 @@ msgstr "окаÑтрÑне на обектите, към които нищо нРmsgid "pack unreferenced objects separately" msgstr "пакетиране на обектите, към които нищо не Ñочи, отделно" +msgid "with --cruft, limit the size of new cruft packs" +msgstr "Ñ â€ž--cruft“ размерът на новите ненужни пакети Ñе ограничава" + msgid "be more thorough (increased runtime)" msgstr "изчерпателно търÑене на боклука (за Ñметка на повече време работа)" @@ -7070,12 +7095,6 @@ msgstr "" msgid "'crontab' died" msgstr "процеÑÑŠÑ‚ на „crontab“ умрÑ" -msgid "failed to start systemctl" -msgstr "неуÑпешно Ñтартиране на „systemctl“" - -msgid "failed to run systemctl" -msgstr "неуÑпешно изпълнение на „systemctl“" - #, c-format msgid "failed to delete '%s'" msgstr "неуÑпешно изтриване на „%s“" @@ -7084,6 +7103,12 @@ msgstr "неуÑпешно изтриване на „%s“" msgid "failed to flush '%s'" msgstr "грешка при изчиÑтването на буферите при запиÑването на „%s“" +msgid "failed to start systemctl" +msgstr "неуÑпешно Ñтартиране на „systemctl“" + +msgid "failed to run systemctl" +msgstr "неуÑпешно изпълнение на „systemctl“" + #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "непознат аргумент към „--scheduler“: %s" @@ -7107,6 +7132,9 @@ msgstr "ПЛÐÐИРÐЩ_МОДУЛ" msgid "scheduler to trigger git maintenance run" msgstr "ПЛÐÐИРÐЩиÑÑ‚_МОДУЛ, който да изпълнÑва задачите" +msgid "failed to set up maintenance schedule" +msgstr "неуÑпешно наÑрочване на задачите по поддръжка" + msgid "failed to add repo to global config" msgstr "неуÑпешно добавÑне на хранилище към файла Ñ Ð³Ð»Ð¾Ð±Ð°Ð»Ð½Ð¸ наÑтройки" @@ -7138,6 +7166,10 @@ msgid "unable to read tree (%s)" msgstr "дървото не може да бъде прочетено (%s)" #, c-format +msgid "unable to read tree %s" +msgstr "дървото не може да бъде прочетено: %s" + +#, c-format msgid "unable to grep from object of type %s" msgstr "не може да Ñе изпълни „grep“ от обект от вида %s" @@ -7182,7 +7214,7 @@ msgstr "" msgid "search in subdirectories (default)" msgstr "търÑене в поддиректориите (Ñтандартно)" -msgid "descend at most <depth> levels" +msgid "descend at most <n> levels" msgstr "навлизане макÑимално на тази ДЪЛБОЧИÐРв дървото" msgid "use extended POSIX regular expressions" @@ -7335,7 +7367,7 @@ msgid "" "git hash-object [-t <type>] [-w] [--path=<file> | --no-filters]\n" " [--stdin [--literally]] [--] <file>..." msgstr "" -"git hash-object [-t ВИД] [-w] [--path=ФÐЙЛ | --no-filters]\n" +"git hash-object [-t ВИД] [-w] [--path=ФÐЙЛ|--no-filters]\n" " [--stdin [--literally]] [--] ФÐЙЛ…" msgid "git hash-object [-t <type>] [-w] --stdin-paths [--no-filters]" @@ -7559,10 +7591,6 @@ msgstr "" "СЪВПÐДЕÐИЕ ÐРСТОЙÐОСТИТЕ ЗРСУМИТЕ ЗРSHA1: „%s“ ÐРДВРРÐЗЛИЧÐИ ОБЕКТÐ!" #, c-format -msgid "unable to read %s" -msgstr "обектът „%s“ не може да бъде прочетен" - -#, c-format msgid "cannot read existing object info %s" msgstr "ÑъщеÑтвуващиÑÑ‚ обект в „%s“ не може да бъде прочетен" @@ -7701,89 +7729,16 @@ msgstr "опциÑта „--verify“ изиÑква име на пакетен msgid "fsck error in pack objects" msgstr "грешка при проверка Ñ â€žfsck“ на пакетните обекти" -#, c-format -msgid "cannot stat template '%s'" -msgstr "не може да Ñе получи Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ñ‡Ñ€ÐµÐ· „stat“ за шаблона „%s“" - -#, c-format -msgid "cannot opendir '%s'" -msgstr "директориÑта „%s“ не може да бъде отворена" - -#, c-format -msgid "cannot readlink '%s'" -msgstr "връзката „%s“ не може да бъде прочетена" - -#, c-format -msgid "cannot symlink '%s' '%s'" -msgstr "не може да Ñе Ñъздаде Ñимволна връзка „%s“ в „%s“" - -#, c-format -msgid "cannot copy '%s' to '%s'" -msgstr "„%s“ не може да Ñе копира в „%s“" - -#, c-format -msgid "ignoring template %s" -msgstr "игнориране на шаблона „%s“" - -#, c-format -msgid "templates not found in %s" -msgstr "нÑма шаблони в „%s“" - -#, c-format -msgid "not copying templates from '%s': %s" -msgstr "шаблоните нÑма да бъдат копирани от „%s“: „%s“" - -#, c-format -msgid "invalid initial branch name: '%s'" -msgstr "неправилно име на Ð¿ÑŠÑ€Ð²Ð¾Ð½Ð°Ñ‡Ð°Ð»Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½: „%s“" - -#, c-format -msgid "unable to handle file type %d" -msgstr "файлове от вид %d не Ñе поддържат" - -#, c-format -msgid "unable to move %s to %s" -msgstr "„%s“ не може да Ñе премеÑти в „%s“" - -msgid "attempt to reinitialize repository with different hash" -msgstr "" -"опит за повторно задаване на първото подаване в хранилището Ñ Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð½Ð° " -"контролна Ñума" - -#, c-format -msgid "%s already exists" -msgstr "ДиректориÑта „%s“ вече ÑъщеÑтвува" - -#, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "re-init: „--initial-branch=%s“ Ñе пропуÑка" - -#, c-format -msgid "Reinitialized existing shared Git repository in %s%s\n" -msgstr "" -"Инициализиране наново на ÑъщеÑтвуващо, Ñподелено хранилище на Git в „%s%s“\n" - -#, c-format -msgid "Reinitialized existing Git repository in %s%s\n" -msgstr "Инициализиране наново на ÑъщеÑтвуващо хранилище на Git в „%s%s“\n" - -#, c-format -msgid "Initialized empty shared Git repository in %s%s\n" -msgstr "Инициализиране на празно, Ñподелено хранилище на Git в „%s%s“\n" - -#, c-format -msgid "Initialized empty Git repository in %s%s\n" -msgstr "Инициализиране на празно хранилище на Git в „%s%s“\n" - msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" -"git init [-q | --quiet] [--bare] [--template=ДИРЕКТОРИЯ_С_ШÐБЛОÐИ]\n" +"git init [-q|--quiet] [--bare] [--template=ДИРЕКТОРИЯ_С_ШÐБЛОÐИ]\n" " [--separate-git-dir ДИРЕКТОРИЯ_ÐÐ_GIT] [--object-format=ФОРМÐТ]\n" -" [-b КЛОР| --initial-branch=КЛОÐ]\n" +" [-b КЛОÐ|--initial-branch=КЛОÐ]\n" " [--shared[=ПРÐÐ’ÐÌ€]] [ДИРЕКТОРИЯ]" msgid "permissions" @@ -7828,11 +7783,11 @@ msgstr "опциÑта „--separate-git-dir“ е неÑъвмеÑтима Ñ Ð msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer ЛЕКСЕМÐ[(=|:)СТОЙÐОСТ])…]\n" +" [(--trailer (КЛЮЧ|СИÐОÐИМ)[(=|:)СТОЙÐОСТ])…]\n" " [--parse] [ФÐЙЛ…]" msgid "edit files in place" @@ -7841,6 +7796,9 @@ msgstr "директно редактиране на файловете" msgid "trim empty trailers" msgstr "изчиÑтване на празните епилози" +msgid "placement" +msgstr "меÑтоположение" + msgid "where to place the new trailer" msgstr "къде да Ñе поÑтави новиÑÑ‚ епилог" @@ -7853,17 +7811,19 @@ msgstr "дейÑтвие при липÑващ епилог" msgid "output only the trailers" msgstr "извеждане Ñамо на епилозите" -msgid "do not apply config rules" -msgstr "без прилагане на правилата за наÑтройките" +msgid "do not apply trailer.* configuration variables" +msgstr "без прилагане на конфигуриращи променливи, завършващи Ñ ÐµÐ¿Ð¸Ð»Ð¾Ð³.*" -msgid "join whitespace-continued values" -msgstr "Ñливане на ÑтойноÑтите поÑледване от знаци за интервали" +msgid "reformat multiline trailer values as single-line values" +msgstr "" +"форматиране на епилози, които заемат повече от един ред, в ÑтойноÑти на един " +"ред" -msgid "set parsing options" -msgstr "опции при анализ" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "пÑевдоним на комбинациÑта „--only-trailers --only-input --unfold“" -msgid "do not treat --- specially" -msgstr "„---“ нÑма Ñпециално значение" +msgid "do not treat \"---\" as the end of input" +msgstr "„---“ не отбелÑзва ÐºÑ€Ð°Ñ Ð½Ð° входа" msgid "trailer(s) to add" msgstr "епилози за добавÑне" @@ -7952,6 +7912,10 @@ msgstr "трÑбва да зададете точно един диапазон" msgid "not a range" msgstr "не е диапазон" +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "файлът Ñ Ð¾Ð¿Ð¸Ñанието на клона „%s“ не може да бъде прочетен" + msgid "cover letter needs email format" msgstr "придружаващото пиÑмо трÑбва да е форматирано като е-пиÑмо" @@ -7963,7 +7927,7 @@ msgid "insane in-reply-to: %s" msgstr "неправилен формат на заглавната чаÑÑ‚ за отговор „in-reply-to“: %s" msgid "git format-patch [<options>] [<since> | <revision-range>]" -msgstr "git format-patch [ОПЦИЯ…] [ОТ | ДИÐПÐЗОÐ_ÐÐ_ВЕРСИИТЕ]" +msgstr "git format-patch [ОПЦИЯ…] [ОТ|ДИÐПÐЗОÐ_ÐÐ_ВЕРСИИТЕ]" msgid "two output directories?" msgstr "може да укажете макÑимум една Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð·Ð° изход" @@ -8054,6 +8018,9 @@ msgstr "" "генериране на чаÑтите на придружаващото пиÑмо на базата на опиÑанието на " "клона" +msgid "use branch description from file" +msgstr "ползване на опиÑание на клон от файл" + msgid "use [<prefix>] instead of [PATCH]" msgstr "използване на този „[ПРЕФИКС]“ вмеÑто „[PATCH]“" @@ -8226,6 +8193,10 @@ msgstr "" "ОТДÐЛЕЧЕÐ_КЛОÐ.\n" #, c-format +msgid "could not get object info about '%s'" +msgstr "не може да Ñе получи Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° обекта „%s“" + +#, c-format msgid "bad ls-files format: element '%s' does not start with '('" msgstr "неправилен формат за „ls-tree“: елементът „%s“ не започва Ñ â€ž(“" @@ -8337,7 +8308,7 @@ msgid "" " [--symref] [<repository> [<patterns>...]]" msgstr "" "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=КОМÐÐДÐ]\n" -" [-q | --quiet] [--exit-code] [--get-url] [--sort=КЛЮЧ]\n" +" [-q|--quiet] [--exit-code] [--get-url] [--sort=КЛЮЧ]\n" " [--symref] [ХРÐÐИЛИЩЕ [ШÐБЛОÐ]]" msgid "do not print remote URL" @@ -8371,10 +8342,6 @@ msgid "git ls-tree [<options>] <tree-ish> [<path>...]" msgstr "git ls-tree [ОПЦИЯ…] УКÐЗÐТЕЛ_КЪМ_ДЪРВО [ПЪТ…]" #, c-format -msgid "could not get object info about '%s'" -msgstr "не може да Ñе получи Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° обекта „%s“" - -#, c-format msgid "bad ls-tree format: element '%s' does not start with '('" msgstr "неправилен формат за „ls-tree“: елементът „%s“ не започва Ñ â€ž(“" @@ -8467,10 +8434,10 @@ msgid "empty mbox: '%s'" msgstr "празна пощенÑка ÐºÑƒÑ‚Ð¸Ñ mbox: „%s“" msgid "git merge-base [-a | --all] <commit> <commit>..." -msgstr "git merge-base [-a | --all] ПОДÐÐ’ÐÐЕ ПОДÐÐ’ÐÐЕ…" +msgstr "git merge-base [-a|--all] ПОДÐÐ’ÐÐЕ ПОДÐÐ’ÐÐЕ…" msgid "git merge-base [-a | --all] --octopus <commit>..." -msgstr "git merge-base [-a | --all] --octopus ПОДÐÐ’ÐÐЕ…" +msgstr "git merge-base [-a|--all] --octopus ПОДÐÐ’ÐÐЕ…" msgid "git merge-base --is-ancestor <commit> <commit>" msgstr "git merge-base --is-ancestor ПОДÐÐ’ÐÐЕ_1 ПОДÐÐ’ÐÐЕ_2" @@ -8504,9 +8471,20 @@ msgstr "" "git merge-file [ОПЦИЯ…] [-L ИМЕ_1 [-L ОРИГИÐÐЛ [-L ИМЕ_2]]] ФÐЙЛ_1 ОРИГ_ФÐЙЛ " "ФÐЙЛ_2" +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"опциÑта приема Ñледните варианти за алгоритъм за разлики: „myers“ (по " +"МайерÑ), „minimal“ (минимизиране на разликите), „patience“ (паÑианÑ) и " +"„histogram“ (хиÑтограмен)" + msgid "send results to standard output" msgstr "извеждане на резултатите на ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð¸Ð·Ñ…Ð¾Ð´" +msgid "use object IDs instead of filenames" +msgstr "ползване на идентификатори на обекти вмеÑто имена на файлове" + msgid "use a diff3 based merge" msgstr "Ñливане на базата на „diff3“" @@ -8522,6 +8500,12 @@ msgstr "при конфликти да Ñе ползва чуждата Ð²ÐµÑ€Ñ msgid "for conflicts, use a union version" msgstr "при конфликти да Ñе ползва обединена верÑиÑ" +msgid "<algorithm>" +msgstr "ÐЛГОРИТЪМ" + +msgid "choose a diff algorithm" +msgstr "избор на ÐЛГОРИТЪМа за разлики" + msgid "for conflicts, use this marker size" msgstr "при конфликти да Ñе ползва маркер Ñ Ñ‚Ð°ÐºÑŠÐ² БРОЙ знаци" @@ -8532,6 +8516,13 @@ msgid "set labels for file1/orig-file/file2" msgstr "задаване на етикети за ФÐЙЛ_1/ОРИГИÐÐЛ/ФÐЙЛ_2" #, c-format +msgid "object '%s' does not exist" +msgstr "обектът „%s“ не ÑъщеÑтвува" + +msgid "Could not write object file" +msgstr "Файлът Ñ Ð¾Ð±ÐµÐºÑ‚Ð¸ не може да Ñе запише" + +#, c-format msgid "unknown option %s" msgstr "непозната опциÑ: „%s“" @@ -8550,7 +8541,7 @@ msgstr "поддържа Ñе Ñамо Ñливане на точно две Ð¸Ñ #, c-format msgid "could not resolve ref '%s'" -msgstr "указателÑÑ‚ „%s“ не може да бъде изтрит" +msgstr "указателÑÑ‚ „%s“ не може да бъде проÑледен" #, c-format msgid "Merging %s with %s\n" @@ -8593,11 +8584,18 @@ msgstr "извършване на множеÑтво ÑливаниÑ, по ед msgid "specify a merge-base for the merge" msgstr "база за Ñливането" +msgid "option=value" +msgstr "ОПЦИЯ=СТОЙÐОСТ" + +msgid "option for selected merge strategy" +msgstr "ОПЦИЯ за избраната ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð·Ð° Ñливане" + msgid "--trivial-merge is incompatible with all other options" msgstr "„--trivial-merge“ е неÑъвмеÑтима Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ‚Ðµ опции" -msgid "--merge-base is incompatible with --stdin" -msgstr "опциите „--merge-base“ и „--stdin“ Ñа неÑъвмеÑтими" +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "непозната Ð¾Ð¿Ñ†Ð¸Ñ Ð·Ð° ÑтратегиÑ: -X%s" #, c-format msgid "malformed input line: '%s'." @@ -8641,7 +8639,7 @@ msgstr "(пÑевдоним на „--stat“)" msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "добавÑне (на макÑимум такъв БРОЙ) запиÑи от ÑÑŠÐºÑ€Ð°Ñ‚ÐµÐ½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð» в Ñъобщението " -"за подаване" +"за подаване ÑÑŠÑ Ñливане" msgid "create a single commit instead of doing a merge" msgstr "Ñъздаване на едно подаване вмеÑто извършване на Ñливане" @@ -8667,12 +8665,6 @@ msgstr "СТРÐТЕГИЯ" msgid "merge strategy to use" msgstr "СТРÐТЕГИЯ за Ñливане, коÑто да Ñе ползва" -msgid "option=value" -msgstr "ОПЦИЯ=СТОЙÐОСТ" - -msgid "option for selected merge strategy" -msgstr "ОПЦИЯ за избраната ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð·Ð° Ñливане" - msgid "merge commit message (for a non-fast-forward merge)" msgstr "СЪОБЩЕÐИЕ при подаването ÑÑŠÑ Ñливане (при ÑъщинÑки ÑливаниÑ)" @@ -8736,10 +8728,6 @@ msgid "Not handling anything other than two heads merge." msgstr "Поддържа Ñе Ñамо Ñливане на точно две иÑтории." #, c-format -msgid "unknown strategy option: -X%s" -msgstr "непозната Ð¾Ð¿Ñ†Ð¸Ñ Ð·Ð° ÑтратегиÑ: -X%s" - -#, c-format msgid "unable to write %s" msgstr "„%s“ не може да бъде запиÑан" @@ -9044,8 +9032,8 @@ msgstr "целта ÑъщеÑтвува" msgid "can not move directory into itself" msgstr "Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ може да Ñе премеÑти в Ñебе Ñи" -msgid "cannot move directory over file" -msgstr "Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ може да Ñе премеÑти върху файл" +msgid "destination already exists" +msgstr "целта ÑъщеÑтвува" msgid "source directory is empty" msgstr "първоначалната Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ðµ празна" @@ -9126,22 +9114,26 @@ msgid "git notes [--ref <notes-ref>] [list [<object>]]" msgstr "git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] [list [ОБЕКТ]]" msgid "" -"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> " -"| (-c | -C) <object>] [<object>]" +"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" +"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " +"| -C) <object>] [<object>]" msgstr "" -"git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] add [-f] [--allow-empty] [-m СЪОБЩЕÐИЕ " -"| -F ФÐЙЛ | (-c | -C) ОБЕКТ] [ОБЕКТ]" +"git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] add [-f] [--allow-empty] [--" +"[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m " +"СЪОБЩЕÐИЕ|-F ФÐЙЛ|(-c|-C) ОБЕКТ] [ОБЕКТ]" msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "" "git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] copy [-f] ОБЕКТ_ИЗТОЧÐИК ОБЕКТ_ЦЕЛ" msgid "" -"git notes [--ref <notes-ref>] append [--allow-empty] [-m <msg> | -F <file> | " -"(-c | -C) <object>] [<object>]" +"git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" +"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " +"| -C) <object>] [<object>]" msgstr "" -"git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] append [--allow-empty] [-m СЪОБЩЕÐИЕ | " -"-F ФÐЙЛ | (-c | -C) ОБЕКТ] [ОБЕКТ]" +"git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] append [--allow-empty] [--" +"[no-]separator|--separator=КРÐЙ_ÐÐ_ÐБЗÐЦ] [--[no-]stripspace] [-m СЪОБЩЕÐИЕ " +"| -F ФÐЙЛ|(-c|-C) ОБЕКТ] [ОБЕКТ]" msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] edit [--allow-empty] [ОБЕКТ]" @@ -9152,7 +9144,7 @@ msgstr "git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] show [ОБЕКТ] msgid "" "git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>" msgstr "" -"git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] merge [-v | -q] [-s СТРÐТЕГИЯ] " +"git notes [--ref УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ] merge [-v|-q] [-s СТРÐТЕГИЯ] " "УКÐЗÐТЕЛ_ЗÐ_БЕЛЕЖКÐ" msgid "git notes [--ref <notes-ref>] remove [<object>...]" @@ -9276,6 +9268,15 @@ msgstr "приемане и на празни бележки" msgid "replace existing notes" msgstr "замÑна на ÑъщеÑтвуващите бележки" +msgid "<paragraph-break>" +msgstr "КРÐЙ_ÐÐ_ÐБЗÐЦ" + +msgid "insert <paragraph-break> between paragraphs" +msgstr "вмъкване на такъв КРÐЙ_ÐÐ_ÐБЗÐЦ между абзаците" + +msgid "remove unnecessary whitespace" +msgstr "премахване на излишните знаци за интервали" + #, c-format msgid "" "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -9440,12 +9441,12 @@ msgstr "непозната подкоманда: „%s“" msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" msgstr "" -"git pack-objects --stdout [ОПЦИЯ…] [< СПИСЪК_С_УКÐЗÐТЕЛИ | < СПИСЪК_С_ОБЕКТИ]" +"git pack-objects --stdout [ОПЦИЯ…] [< СПИСЪК_С_УКÐЗÐТЕЛИ|< СПИСЪК_С_ОБЕКТИ]" msgid "" "git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" msgstr "" -"git pack-objects [ОПЦИЯ…] ПРЕФИКС_ÐÐ_ИМЕТО [< СПИСЪК_С_УКÐЗÐТЕЛИ | < " +"git pack-objects [ОПЦИЯ…] ПРЕФИКС_ÐÐ_ИМЕТО [< СПИСЪК_С_УКÐЗÐТЕЛИ|< " "СПИСЪК_С_ОБЕКТИ]" #, c-format @@ -9555,6 +9556,11 @@ msgid "inconsistency with delta count" msgstr "неправилен брой разлики" #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "" +"неправилна ÑтойноÑÑ‚ за преизползването на пакети „pack.allowPackReuse“: „%s“" + +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -9582,13 +9588,13 @@ msgid "packfile %s cannot be accessed" msgstr "пакетниÑÑ‚ файл „%s“ не може да бъде доÑтъпен" msgid "Enumerating cruft objects" -msgstr "ИзброÑване на излишните обекти" +msgstr "ИзброÑване на ненужните обекти" msgid "unable to add cruft objects" -msgstr "неуÑпешно добавÑне на излишни обекти" +msgstr "неуÑпешно добавÑне на ненужни обекти" msgid "Traversing cruft objects" -msgstr "Обхождане на излишните обекти" +msgstr "Обхождане на ненужните обекти" #, c-format msgid "" @@ -9608,7 +9614,7 @@ msgstr "" msgid "could not load cruft pack .mtimes" msgstr "" -"времената на промÑна (.mtimes) на пакета Ñ Ð¸Ð·Ð»Ð¸ÑˆÐ½Ð¸ файлове не може да Ñе " +"времената на промÑна (.mtimes) на пакета Ñ Ð½ÐµÐ½ÑƒÐ¶Ð½Ð¸ файлове не може да Ñе " "заредÑÑ‚" msgid "cannot open pack index" @@ -9727,10 +9733,10 @@ msgid "unpack unreachable objects newer than <time>" msgstr "разпакетиране на недоÑтижимите обекти, които Ñа по-нови от това ВРЕМЕ" msgid "create a cruft pack" -msgstr "Ñъздаване на пакет Ñ Ð¸Ð·Ð»Ð¸ÑˆÐ½Ð¸Ñ‚Ðµ обекти" +msgstr "Ñъздаване на пакет Ñ Ð½ÐµÐ½ÑƒÐ¶Ð½Ð¸Ñ‚Ðµ обекти" msgid "expire cruft objects older than <time>" -msgstr "обÑвÑване на излишните обекти по-Ñтари от това ВРЕМЕ за оÑтарели" +msgstr "обÑвÑване на ненужните обекти по-Ñтари от това ВРЕМЕ за оÑтарели" msgid "use the sparse reachability algorithm" msgstr "използване на алгоритъм за чаÑтична доÑтижимоÑÑ‚" @@ -9808,9 +9814,6 @@ msgstr "" "опциÑта „--thin“не може да Ñе използва за Ñъздаване на пакетни файлове Ñ " "индекÑ" -msgid "cannot use --filter without --stdout" -msgstr "опциÑта „--filter“ изиÑква „--stdout“" - msgid "cannot use --filter with --stdin-packs" msgstr "опциите „--filter“ и „--stdin-packs“ Ñа неÑъвмеÑтими" @@ -9824,19 +9827,16 @@ msgstr "вътрешниÑÑ‚ ÑпиÑък на верÑии и опциÑта †msgid "cannot use --stdin-packs with --cruft" msgstr "опциите „--stdin-packs“ и „--cruft“ Ñа неÑъвмеÑтими" -msgid "cannot use --max-pack-size with --cruft" -msgstr "опциите „--max-pack-size“ и „--cruft“ Ñа неÑъвмеÑтими" - msgid "Enumerating objects" msgstr "ИзброÑване на обектите" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "Общо: %<PRIu32> (разлики: %<PRIu32>), преизползвани: %<PRIu32> (разлики: " -"%<PRIu32>), преизползвани при пакетиране: %<PRIu32>" +"%<PRIu32>), преизползвани при пакетиране: %<PRIu32> (от %<PRIuMAX>)" msgid "" "'git pack-redundant' is nominated for removal.\n" @@ -9854,8 +9854,11 @@ msgstr "" msgid "refusing to run without --i-still-use-this" msgstr "трÑбва да добавите и опциÑта „--i-still-use-this“" -msgid "git pack-refs [--all] [--no-prune]" -msgstr "git pack-refs [--all] [--no-prune]" +msgid "" +"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude " +"<pattern>]" +msgstr "" +"git pack-refs [--all] [--no-prune] [--include ШÐБЛОÐ] [--exclude ШÐБЛОÐ]" msgid "pack everything" msgstr "пакетиране на вÑичко" @@ -9863,14 +9866,20 @@ msgstr "пакетиране на вÑичко" msgid "prune loose refs (default)" msgstr "окаÑтрÑне на недоÑтижимите указатели (Ñтандартно)" +msgid "references to include" +msgstr "кои указатели да Ñе включат" + +msgid "references to exclude" +msgstr "кои указатели да Ñе преÑкочат" + msgid "git patch-id [--stable | --unstable | --verbatim]" -msgstr "git patch-id [--stable | --unstable | --verbatim]" +msgstr "git patch-id [--stable|--unstable|--verbatim]" msgid "use the unstable patch-id algorithm" -msgstr "използване на неÑтабилен алгоритъм за идентифициране на кръпка" +msgstr "използване на неÑÑ‚Ð°Ð±Ð¸Ð»Ð½Ð¸Ñ Ð°Ð»Ð³Ð¾Ñ€Ð¸Ñ‚ÑŠÐ¼ за идентифициране на кръпка" msgid "use the stable patch-id algorithm" -msgstr "използване на Ñтабилен алгоритъм за идентифициране на кръпка" +msgstr "използване на ÑÑ‚Ð°Ð±Ð¸Ð»Ð½Ð¸Ñ Ð°Ð»Ð³Ð¾Ñ€Ð¸Ñ‚ÑŠÐ¼ за идентифициране на кръпка" msgid "don't strip whitespace from the patch" msgstr "без махане на празните знаци в кръпката" @@ -9922,6 +9931,12 @@ msgstr "принудително презапиÑване на Ð»Ð¾ÐºÐ°Ð»Ð½Ð¸Ñ msgid "number of submodules pulled in parallel" msgstr "брой подмодули издърпани паралелно" +msgid "use IPv4 addresses only" +msgstr "Ñамо адреÑи IPv4" + +msgid "use IPv6 addresses only" +msgstr "Ñамо адреÑи IPv6" + msgid "" "There is no candidate for rebasing against among the refs that you just " "fetched." @@ -10023,7 +10038,7 @@ msgstr "" "приоритет пред наÑтройките.\n" msgid "Updating an unborn branch with changes added to the index." -msgstr "ОбновÑване на вÑе още неÑъздаден клон Ñ Ð¿Ñ€Ð¾Ð¼ÐµÌ€Ð½Ð¸Ñ‚Ðµ от индекÑа" +msgstr "ОбновÑване на неродѐн клон Ñ Ð¿Ñ€Ð¾Ð¼ÐµÌ€Ð½Ð¸Ñ‚Ðµ от индекÑа" msgid "pull with rebase" msgstr "издърпване Ñ Ð¿Ñ€ÐµÐ±Ð°Ð·Ð¸Ñ€Ð°Ð½Ðµ" @@ -10187,35 +10202,37 @@ msgstr "" 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" +"its remote counterpart. If you want to integrate the remote changes,\n" +"use 'git pull' before pushing again.\n" "See the 'Note about fast-forwards' in 'git push --help' for details." msgstr "" -"ОбновÑването е отхвърлено, защото върхът на Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð²Ð¸ клон е преди върха " -"на\n" +"ОбновÑването е отхвърлено, защото върхът на Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð²Ð¸ клон Ñледва върха на\n" "Ð¾Ñ‚Ð´Ð°Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½. ВнеÑете отдалечените промѐни (напр. Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð° „git " "pull…“),\n" -"преди отново да изтлаÑкате промѐните. За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð²Ð¸Ð¶Ñ‚Ðµ раздела\n" -"„Note about fast-forwards“ в Ñтраницата от ръководÑтвото „git push --help“." +"преди отново да изтлаÑкате промѐните.\n" +"За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð²Ð¸Ð¶Ñ‚Ðµ раздела „Note about fast-forwards“ в Ñтраницата " +"от\n" +"ръководÑтвото „git push --help“." 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" +"counterpart. If you want to integrate the remote changes, use 'git pull'\n" +"before pushing again.\n" "See the 'Note about fast-forwards' in 'git push --help' for details." msgstr "" -"ОбновÑването е отхвърлено, защото върхът на изтлаÑÐºÐ²Ð°Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½ е преди върха\n" +"ОбновÑването е отхвърлено, защото върхът на изтлаÑÐºÐ²Ð°Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½ Ñледва върха\n" "на Ð¾Ñ‚Ð´Ð°Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½. Преминете към клона и внеÑете отдалечените промѐни " "(напр.\n" -"Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð° „git pull…“), преди отново да изтлаÑкате промѐните. За повече\n" -"Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾Ð³Ð»ÐµÐ´Ð½ÐµÑ‚Ðµ раздела „Note about fast-forwards“ в Ñтраницата от\n" +"Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð° „git pull…“), преди отново да изтлаÑкате промѐните.\n" +"За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð²Ð¸Ð¶Ñ‚Ðµ раздела „Note about fast-forwards“ в Ñтраницата " +"от\n" "ръководÑтвото „git push --help“." 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" +"Updates were rejected because the remote contains work that you do not\n" +"have locally. This is usually caused by another repository pushing to\n" +"the same ref. If you want to integrate the remote changes, use\n" +"'git pull' before pushing again.\n" "See the 'Note about fast-forwards' in 'git push --help' for details." msgstr "" "ОбновÑването е отхвърлено, защото хранилището, към което изтлаÑквате, " @@ -10245,14 +10262,17 @@ msgstr "" "да го променÑте да Ñочи към подобен обект.\n" 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" +"Updates were rejected because the tip of the remote-tracking branch has\n" +"been updated since the last checkout. If you want to integrate the\n" +"remote changes, use 'git pull' before pushing again.\n" +"See the 'Note about fast-forwards' in 'git push --help' for details." msgstr "" -"ОбновÑването е отхвърлено, защото върхът на ÑледÑÑ‰Ð¸Ñ ÐºÐ»Ð¾Ð½ е обновÑван Ñлед\n" -"поÑледното изтеглÑне. ВнеÑете отдалечените промѐни (напр. Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð°\n" -"„git pull…“), преди отново принудително да изтлаÑкате промѐните.\n" +"ОбновÑването е отхвърлено, защото върхът на Ð¾Ñ‚Ð´Ð°Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½ Ñъдържа " +"промени\n" +"Ñлед поÑледното изтеглÑне. ВнеÑете отдалечените промѐни (напр. Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð°\n" +"„git pull…“), преди отново да изтлаÑкате промѐните.\n" +"За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð²Ð¸Ð¶Ñ‚Ðµ раздела „Note about fast-forwards“ в Ñтраницата\n" +"от ръководÑтвото „git push --help“." #, c-format msgid "Pushing to %s\n" @@ -10414,9 +10434,9 @@ msgid "" " [-u | -i]] [--index-output=<file>] [--no-sparse-checkout]\n" " (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])" msgstr "" -"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=ПРЕФИКС)\n" -" [-u | -i]] [--index-output=ФÐЙЛ] [--no-sparse-checkout]\n" -" (--empty | УКÐЗÐТЕЛ_КЪМ_ДЪРВО_1 [УКÐЗÐТЕЛ_КЪМ_ДЪРВО_2 " +"git read-tree [(-m [--trivial] [--aggressive]|--reset|--prefix=ПРЕФИКС)\n" +" [-u|-i]] [--index-output=ФÐЙЛ] [--no-sparse-checkout]\n" +" (--empty|УКÐЗÐТЕЛ_КЪМ_ДЪРВО_1 [УКÐЗÐТЕЛ_КЪМ_ДЪРВО_2 " "[УКÐЗÐТЕЛ_КЪМ_ДЪРВО_3]])" msgid "write resulting index to <file>" @@ -10477,7 +10497,7 @@ msgid "" "git rebase [-i] [options] [--exec <cmd>] [--onto <newbase> | --keep-base] " "[<upstream> [<branch>]]" msgstr "" -"git rebase [-i] [ОПЦИЯ…] [--exec КОМÐÐДÐ] [--onto ÐОВÐ_БÐЗР| --keep-base] " +"git rebase [-i] [ОПЦИЯ…] [--exec КОМÐÐДÐ] [--onto ÐОВÐ_БÐЗÐ|--keep-base] " "[КЛОÐ_ИЗТОЧÐИК [КЛОÐ]]" msgid "" @@ -10809,17 +10829,6 @@ msgstr "" msgid "switch `C' expects a numerical value" msgstr "опциÑта „C“ очаква чиÑло за аргумент" -msgid "--strategy requires --merge or --interactive" -msgstr "" -"опциÑта „--strategy“ изиÑква нÑÐºÐ¾Ñ Ð¾Ñ‚ опциите „--merge“ или „--interactive“" - -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "" -"опциите за прилагане Ñа неÑъвмеÑтими Ñ â€žrebase.autoSquash“. Пробвайте да " -"добавите опциÑта „--no-autosquash“" - msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -10983,7 +10992,7 @@ msgid "" msgstr "" "git reflog expire [--expire=ВРЕМЕ] [--expire-unreachable=ВРЕМЕ]\n" " [--rewrite] [--updateref] [--stale-fix]\n" -" [--dry-run | -n] [--verbose] [--all [--single-worktree] | " +" [--dry-run|-n] [--verbose] [--all [--single-worktree]|" "УКÐЗÐТЕЛ…]" msgid "" @@ -10991,7 +11000,7 @@ msgid "" " [--dry-run | -n] [--verbose] <ref>@{<specifier>}..." msgstr "" "git reflog delete [--rewrite] [--updateref]\n" -" [--dry-run | -n] [--verbose] УКÐЗÐТЕЛ@{УТОЧÐЕÐИЕ}…" +" [--dry-run|-n] [--verbose] УКÐЗÐТЕЛ@{УТОЧÐЕÐИЕ}…" msgid "git reflog exists <ref>" msgstr "git reflog exists УКÐЗÐТЕЛ" @@ -11059,7 +11068,7 @@ msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" msgstr "" -"git remote add [-t КЛОÐ] [-m ОСÐОВЕÐ_КЛОÐ] [-f] [--tags | --no-tags] [--" +"git remote add [-t КЛОÐ] [-m ОСÐОВЕÐ_КЛОÐ] [-f] [--tags|--no-tags] [--" "mirror=<fetch|push>] ИМЕ ÐДРЕС" msgid "git remote rename [--[no-]progress] <old> <new>" @@ -11069,19 +11078,18 @@ msgid "git remote remove <name>" msgstr "git remote remove ИМЕ" msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)" -msgstr "git remote set-head ИМЕ (-a | --auto | -d | --delete | КЛОÐ)" +msgstr "git remote set-head ИМЕ (-a|--auto|-d|--delete|КЛОÐ)" msgid "git remote [-v | --verbose] show [-n] <name>" -msgstr "git remote [-v | --verbose] show [-n] ИМЕ" +msgstr "git remote [-v|--verbose] show [-n] ИМЕ" msgid "git remote prune [-n | --dry-run] <name>" -msgstr "git remote prune [-n | --dry-run] ИМЕ" +msgstr "git remote prune [-n|--dry-run] ИМЕ" msgid "" "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]" msgstr "" -"git remote [-v | --verbose] update [-p | --prune] [(ГРУПР| " -"ОТДÐЛЕЧЕÐО_ХРÐÐИЛИЩЕ)…]" +"git remote [-v|--verbose] update [-p|--prune] [(ГРУПÐ|ОТДÐЛЕЧЕÐО_ХРÐÐИЛИЩЕ)…]" msgid "git remote set-branches [--add] <name> <branch>..." msgstr "git remote set-branches [--add] ИМЕ КЛОÐ…" @@ -11114,7 +11122,7 @@ msgid "git remote prune [<options>] <name>" msgstr "git remote prune [ОПЦИЯ…] ИМЕ" msgid "git remote update [<options>] [<group> | <remote>]..." -msgstr "git remote update [ОПЦИЯ…] [ГРУПР| ОТДÐЛЕЧЕÐО_ХРÐÐИЛИЩЕ…]" +msgstr "git remote update [ОПЦИЯ…] [ГРУПÐ|ОТДÐЛЕЧЕÐО_ХРÐÐИЛИЩЕ…]" #, c-format msgid "Updating %s" @@ -11138,11 +11146,12 @@ msgstr "неправилна ÑтойноÑÑ‚ за „--mirror“: %s" msgid "fetch the remote branches" msgstr "отдалечените клони не може да бъдат доÑтавени" -msgid "import all tags and associated objects when fetching" -msgstr "внаÑÑне на вÑички етикети и принадлежащите им обекти при доÑтавÑне" - -msgid "or do not fetch any tag at all (--no-tags)" -msgstr "може и да не Ñе доÑтавÑÑ‚ никакви етикети (чрез опциÑта „--no-tags“)" +msgid "" +"import all tags and associated objects when fetching\n" +"or do not fetch any tag at all (--no-tags)" +msgstr "" +"внаÑÑне на вÑички етикети и принадлежащите им обекти при доÑтавÑне\n" +"или да не Ñе доÑтавÑÑ‚ никакви етикети (чрез опциÑта „--no-tags“)" msgid "branch(es) to track" msgstr "клон/и за Ñледене" @@ -11541,6 +11550,10 @@ msgstr "временниÑÑ‚ файл ÑÑŠÑ Ñнимка на указателРmsgid "could not remove stale bitmap: %s" msgstr "изтриването на оÑтарÑлата битова маÑка „%s“ е невъзможно" +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "името на Ð¿Ð°ÐºÐµÑ‚Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð» „%s“ не започва Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñта за обекти Ñ â€ž%s“" + msgid "pack everything in a single pack" msgstr "пакетиране на вÑичко в пакет" @@ -11551,7 +11564,7 @@ msgstr "" msgid "same as -a, pack unreachable cruft objects separately" msgstr "" -"Ñъщото като опциÑта „-a“. ÐедоÑтижимите излишни обекти да Ñе пакетират " +"Ñъщото като опциÑта „-a“. ÐедоÑтижимите ненужни обекти да Ñе пакетират " "отделно" msgid "approxidate" @@ -11626,19 +11639,22 @@ msgid "write a multi-pack index of the resulting packs" msgstr "запазване на многопакетен Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð° Ñъздадените пакети" msgid "pack prefix to store a pack containing pruned objects" -msgstr "Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ð½Ð° името на Ð¿Ð°ÐºÐµÑ‚Ð½Ð¸Ñ Ð·Ð° пакети за окаÑтрени обекти" +msgstr "Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ð½Ð° имената на пакетите за окаÑтрени обекти" + +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ð½Ð° имената на пакетите за филтрирани обекти" msgid "cannot delete packs in a precious-objects repo" msgstr "пакетите в хранилище Ñ Ð²Ð°Ð¶Ð½Ð¸ обекти не може да Ñе триÑÑ‚" +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "опциÑта „%s“ изиÑква „%s“" + msgid "Nothing new to pack." msgstr "Ðищо ново за пакетиране" #, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "името на Ð¿Ð°ÐºÐµÑ‚Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð» „%s“ не започва Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñта за обекти Ñ â€ž%s“" - -#, c-format msgid "renaming pack to '%s' failed" msgstr "неуÑпешно преименуване на Ð¿Ð°ÐºÐµÑ‚Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð» на „%s“" @@ -11838,9 +11854,79 @@ msgstr "опциÑта „--convert-graft-file“ не приема аргуме msgid "only one pattern can be given with -l" msgstr "опциÑта „-l“ приема точно един шаблон" +msgid "need some commits to replay" +msgstr "необходимо е да има Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ð·Ð° прилагане отново" + +msgid "--onto and --advance are incompatible" +msgstr "опциите „--onto“ и „--advance“ Ñа неÑъвмеÑтими" + +msgid "all positive revisions given must be references" +msgstr "вÑички зададени положителни верÑии трÑбва да Ñа указатели" + +msgid "argument to --advance must be a reference" +msgstr "аргументът към „--advance“ трÑбва да е указател" + +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "" +"цели Ñ Ð¼Ð½Ð¾Ð¶ÐµÑтво източници не може да Ñе придвижат напред, защото подредбата " +"не е добре дефинирана" + +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "" +"не може да Ñе определи дали това дейÑтвие е за „--advance“ или „--onto“" + +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "" +"цели Ñ Ð¼Ð½Ð¾Ð¶ÐµÑтво клони-източници не може да Ñе придвижат напред, защото " +"подредбата не е добре дефинирана" + +msgid "cannot implicitly determine correct base for --onto" +msgstr "правилната база за „--onto“ не може да Ñе определи" + +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(ЕКСПЕРИМЕÐТÐЛÐО!) git replay ([--contained] --onto ÐОВÐ_БÐЗР| --advance " +"КЛОÐ) ДИÐПÐЗОÐ_ПОДÐÐ’ÐÐИЯ…" + +msgid "make replay advance given branch" +msgstr "прилагането наново придвижва Ð´Ð°Ð´ÐµÐ½Ð¸Ñ ÐšÐ›ÐžÐ Ð½Ð°Ð¿Ñ€ÐµÐ´" + +msgid "replay onto given commit" +msgstr "прилагането наново върху даденото ПОДÐÐ’ÐÐЕ" + +msgid "advance all branches contained in revision-range" +msgstr "придвижване на вÑички КЛОÐи в ДИÐПÐЗОÐа_ПОДÐÐ’ÐÐИЯ" + +msgid "option --onto or --advance is mandatory" +msgstr "изиÑква Ñе нÑÐºÐ¾Ñ Ð¾Ñ‚ опциите „--onto“ или „--advance“" + +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "" +"нÑкои опции за проÑледÑване на указатели ще бъдат променени, защото битът " +"„%s“ в Ñтруктурата „struct rev_info“ има превеÑ" + +msgid "error preparing revisions" +msgstr "грешка при подготовката на верÑии" + +msgid "replaying down to root commit is not supported yet!" +msgstr "не Ñе поддържа прилагане наново и на началното подаване!" + +msgid "replaying merge commits is not supported yet!" +msgstr "не Ñе поддържа прилагане наново и на Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ ÑÑŠÑ Ñливане!" + msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" -msgstr "git rerere [clear | forget ПЪТ… | diff | status | remaining | gc]" +msgstr "git rerere [clear|forget ПЪТ…|diff|status|remaining|gc]" msgid "register clean resolutions in index" msgstr "региÑтриране на чиÑти корекции на конфликти в индекÑа" @@ -11854,8 +11940,7 @@ msgstr "неуÑпешно генериране на разлика за „%s†msgid "" "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" -msgstr "" -"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [ПОДÐÐ’ÐÐЕ]" +msgstr "git reset [--mixed|--soft|--hard|--merge|--keep] [-q] [ПОДÐÐ’ÐÐЕ]" msgid "git reset [-q] [<tree-ish>] [--] <pathspec>..." msgstr "git reset [-q] [УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [--] ПЪТИЩÐ…" @@ -12046,18 +12131,12 @@ msgstr "опциÑта „--prefix“ изиÑква аргумент" msgid "unknown mode for --abbrev-ref: %s" msgstr "непознат режим за „--abbrev-ref“: „%s“" -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "опциите „--exclude-hidden“ и „--branches“ Ñа неÑъвмеÑтими" - -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "опциите „--exclude-hidden“ и „--tags“ Ñа неÑъвмеÑтими" - -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "опциите „--exclude-hidden“ и „--remotes“ Ñа неÑъвмеÑтими" - msgid "this operation must be run in a work tree" msgstr "тази команда трÑбва да Ñе изпълни в работно дърво" +msgid "Could not read the index" +msgstr "ИндекÑÑŠÑ‚ не може да бъде прочетен" + #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "непознат режим за „--show-object-format“: „%s“" @@ -12070,7 +12149,7 @@ msgstr "" " [-S[ИДЕÐТИФИКÐТОР_ÐÐ_КЛЮЧ]] ПОДÐÐ’ÐÐЕ…" msgid "git revert (--continue | --skip | --abort | --quit)" -msgstr "git revert (--continue | --skip | --abort | --quit)" +msgstr "git revert (--continue|--skip|--abort|--quit)" msgid "" "git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]\n" @@ -12080,7 +12159,7 @@ msgstr "" " [-S[ИДЕÐТИФИКÐТОР_ÐÐ_КЛЮЧ]] ПОДÐÐ’ÐÐЕ…" msgid "git cherry-pick (--continue | --skip | --abort | --quit)" -msgstr "git cherry-pick (--continue | --skip | --abort | --quit)" +msgstr "git cherry-pick (--continue|--skip|--abort|--quit)" #, c-format msgid "option `%s' expects a number greater than zero" @@ -12146,7 +12225,7 @@ msgid "" " [--quiet] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n" " [--] [<pathspec>...]" msgstr "" -"git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]\n" +"git rm [-f|--force] [-n] [-r] [--cached] [--ignore-unmatch]\n" " [--quiet] [--pathspec-from-file=ФÐЙЛ [--pathspec-file-nul]]\n" " [--] [ПЪТ…]" @@ -12233,8 +12312,8 @@ msgstr "" "git send-pack [--mirror] [--dry-run] [--force]\n" " [--receive-pack=ПÐКЕТ]\n" " [--verbose] [--thin] [--atomic]\n" -" [--[no-]signed | --signed=(true|false|if-asked)]\n" -" [ХОСТ:]ДИРЕКТОРИЯ (--all | УКÐЗÐТЕЛ…)" +" [--[no-]signed|--signed=(true|false|if-asked)]\n" +" [ХОСТ:]ДИРЕКТОРИЯ (--all|УКÐЗÐТЕЛ…)" msgid "remote name" msgstr "име на отдалечено хранилище" @@ -12302,14 +12381,14 @@ msgid "" " [--no-name | --sha1-name] [--topics]\n" " [(<rev> | <glob>)...]" msgstr "" -"git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n" -" [--current] [--color[=КОГÐ] | --no-color] [--sparse]\n" -" [--more=<n> | --list | --independent | --merge-base]\n" -" [--no-name | --sha1-name] [--topics]\n" -" [(РЕВИЗИЯ | УКÐЗÐТЕЛ)…]" +"git show-branch [-a|--all] [-r|--remotes] [--topo-order|--date-order]\n" +" [--current] [--color[=КОГÐ]|--no-color] [--sparse]\n" +" [--more=<n>|--list|--independent|--merge-base]\n" +" [--no-name|--sha1-name] [--topics]\n" +" [(РЕВИЗИЯ|УКÐЗÐТЕЛ)…]" msgid "git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]" -msgstr "git show-branch (-g | --reflog)[=БРОЙ[,БÐЗÐ]] [--list] [УКÐЗÐТЕЛ]" +msgstr "git show-branch (-g|--reflog)[=БРОЙ[,БÐЗÐ]] [--list] [УКÐЗÐТЕЛ]" #, c-format msgid "ignoring %s; cannot handle more than %d ref" @@ -12408,25 +12487,46 @@ msgid "Unknown hash algorithm" msgstr "Ðепознат алгоритъм за контролни Ñуми" msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" -" [-s | --hash[=БРОЙ]] [--abbrev[=БРОЙ]] [--tags]\n" +"git show-ref [--head] [-d|--dereference]\n" +" [-s|--hash[=БРОЙ]] [--abbrev[=БРОЙ]] [--tags]\n" " [--heads] [--] [ШÐБЛОÐ…]" +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q|--quiet] [-d|--dereference]\n" +" [-s|--hash[=БРОЙ]] [--abbrev[=БРОЙ]]\n" +" [--] [ШÐБЛОÐ…]" + msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=ШÐБЛОÐ]" +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists УКÐЗÐТЕЛ" + +msgid "reference does not exist" +msgstr "указателÑÑ‚ не ÑъщеÑтвува" + +msgid "failed to look up reference" +msgstr "Ñоченото от ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ Ð»Ð¸Ð¿Ñва" + msgid "only show tags (can be combined with heads)" msgstr "извеждане на етикетите (може да Ñе комбинира Ñ Ð²ÑŠÑ€Ñ…Ð¾Ð²ÐµÑ‚Ðµ)" msgid "only show heads (can be combined with tags)" msgstr "извеждане на върховете (може да Ñе комбинира Ñ ÐµÑ‚Ð¸ÐºÐµÑ‚Ð¸Ñ‚Ðµ)" +msgid "check for reference existence without resolving" +msgstr "проверка за ÑъщеÑтвуване на указател без проÑледÑването му" + msgid "stricter reference checking, requires exact ref path" -msgstr "Ñтрога проверка на указателите, изиÑква Ñе указател Ñ Ð¿ÑŠÐ»ÐµÐ½ път" +msgstr "по-Ñтрога проверка за указатели, изиÑква точен път на указател" msgid "show the HEAD reference, even if it would be filtered out" msgstr "задължително извеждане и на ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ HEAD" @@ -12451,8 +12551,7 @@ msgid "" "git sparse-checkout (init | list | set | add | reapply | disable | check-" "rules) [<options>]" msgstr "" -"git sparse-checkout (init | list | set | add | reapply | disable | check-" -"rules) ОПЦИЯ…" +"git sparse-checkout (init|list|set|add|reapply|disable|check-rules) ОПЦИЯ…" msgid "this worktree is not sparse" msgstr "това работно дърво не е чаÑтично" @@ -12549,7 +12648,7 @@ msgstr "" "ръководÑтвото на командата „git-sparse-checkout“)." msgid "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)" -msgstr "git sparse-checkout add [--skip-checks] (--stdin | ШÐБЛОÐ…)" +msgstr "git sparse-checkout add [--skip-checks] (--stdin|ШÐБЛОÐ…)" msgid "" "skip some sanity checks on the given paths that might give false positives" @@ -12568,7 +12667,7 @@ msgid "" "(--stdin | <patterns>)" msgstr "" "git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] " -"(--stdin | ШÐБЛОÐ…)" +"(--stdin|ШÐБЛОÐ…)" msgid "must be in a sparse-checkout to reapply sparsity patterns" msgstr "" @@ -12603,23 +12702,23 @@ msgid "" "git stash show [-u | --include-untracked | --only-untracked] [<diff-" "options>] [<stash>]" msgstr "" -"git stash show [-u | --include-untracked | --only-untracked] " -"[ОПЦИЯ_ЗÐ_Ð ÐЗЛИКÐ…] [СКÐТÐÐО]" +"git stash show [-u|--include-untracked|--only-untracked] [ОПЦИЯ_ЗÐ_Ð ÐЗЛИКÐ…] " +"[СКÐТÐÐО]" msgid "git stash drop [-q | --quiet] [<stash>]" -msgstr "git stash drop [-q | --quiet] [СКÐТÐÐО]" +msgstr "git stash drop [-q|--quiet] [СКÐТÐÐО]" msgid "git stash pop [--index] [-q | --quiet] [<stash>]" -msgstr "git stash pop [--index] [-q | --quiet] [СКÐТÐÐО]" +msgstr "git stash pop [--index] [-q|--quiet] [СКÐТÐÐО]" msgid "git stash apply [--index] [-q | --quiet] [<stash>]" -msgstr "git stash apply [--index] [-q | --quiet] [СКÐТÐÐО]" +msgstr "git stash apply [--index] [-q|--quiet] [СКÐТÐÐО]" msgid "git stash branch <branchname> [<stash>]" msgstr "git stash branch КЛОР[СКÐТÐÐО]" msgid "git stash store [(-m | --message) <message>] [-q | --quiet] <commit>" -msgstr "git stash store [-m | --message СЪОБЩЕÐИЕ] [-q | --quiet] ПОДÐÐ’ÐÐЕ" +msgstr "git stash store [-m|--message СЪОБЩЕÐИЕ] [-q|--quiet] ПОДÐÐ’ÐÐЕ" msgid "" "git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q " @@ -12629,10 +12728,9 @@ msgid "" " [--pathspec-from-file=<file> [--pathspec-file-nul]]\n" " [--] [<pathspec>...]]" msgstr "" -"git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q " -"| --quiet]\n" -" [-u | --include-untracked] [-a | --all] [(-m | --message) " -"СЪОБЩЕÐИЕ]\n" +"git stash [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q | --" +"quiet]\n" +" [-u|--include-untracked] [-a|--all] [(-m|--message) СЪОБЩЕÐИЕ]\n" " [--pathspec-from-file=ФÐЙЛ [--pathspec-file-nul]]\n" " [--] [ПЪТ…]]" @@ -12641,9 +12739,9 @@ msgid "" "--quiet]\n" " [-u | --include-untracked] [-a | --all] [<message>]" msgstr "" -"git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | " -"--quiet]\n" -" [-u | --include-untracked] [-a | --all] [СЪОБЩЕÐИЕ]" +"git stash save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--" +"quiet]\n" +" [-u|--include-untracked] [-a|--all] [СЪОБЩЕÐИЕ]" msgid "git stash create [<message>]" msgstr "git stash create [СЪОБЩЕÐИЕ]" @@ -13022,7 +13120,7 @@ msgstr "премахване на региÑтрациите на вÑички Ð msgid "" "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]" -msgstr "git submodule deinit [--quiet] [-f | --force] [--all | [--] [ПЪТ…]]" +msgstr "git submodule deinit [--quiet] [-f|--force] [--all|[--] [ПЪТ…]]" msgid "Use '--all' if you really want to deinitialize all submodules" msgstr "Използвайте „--all“, за да премахнете вÑички подмодули" @@ -13124,6 +13222,10 @@ msgid "Skipping submodule '%s'" msgstr "ПреÑкачане на подмодула „%s“" #, c-format +msgid "cannot clone submodule '%s' without a URL" +msgstr "не може да Ñе клонира подмодул „%s“ без адреÑ" + +#, c-format msgid "Failed to clone '%s'. Retry scheduled" msgstr "ÐеуÑпешен опит за клониране на „%s“. ÐаÑрочен е втори опит" @@ -13257,6 +13359,9 @@ msgstr "" "shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] " "[--] [ПЪТ…]" +msgid "Failed to resolve HEAD as a valid ref." +msgstr "Ðе може да Ñе открие към какво Ñочи указателÑÑ‚ „HEAD“" + msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [ОПЦИЯ…] [ПЪТ…]" @@ -13429,9 +13534,8 @@ msgid "" "git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n" " <tagname> [<commit> | <object>]" msgstr "" -"git tag [-a | -s | -u ИДЕÐТИФИКÐТОР_ÐÐ_КЛЮЧ] [-f] [-m СЪОБЩЕÐИЕ | -F ФÐЙЛ] [-" -"e]\n" -" ЕТИКЕТ [ПОДÐÐ’ÐÐЕ | ОБЕКТ]" +"git tag [-a|-s|-u ИДЕÐТИФИКÐТОР_ÐÐ_КЛЮЧ] [-f] [-m СЪОБЩЕÐИЕ|-F ФÐЙЛ] [-e]\n" +" ЕТИКЕТ [ПОДÐÐ’ÐÐЕ|ОБЕКТ]" msgid "git tag -d <tagname>..." msgstr "git tag -d ЕТИКЕТ…" @@ -13443,7 +13547,7 @@ msgid "" " [--merged <commit>] [--no-merged <commit>] [<pattern>...]" msgstr "" "git tag [-n[БРОЙ]] -l [--contains ПОДÐÐ’ÐÐЕ] [--no-contains ПОДÐÐ’ÐÐЕ]\n" -" [--points-at ОБЕКТ] [--column[=ОПЦИЯ…] | --no-column]\n" +" [--points-at ОБЕКТ] [--column[=ОПЦИЯ…]|--no-column]\n" " [--create-reflog] [--sort=<key>] [--format=ФОРМÐТ]\n" " [--merged ПОДÐÐ’ÐÐЕ] [--no-merged ПОДÐÐ’ÐÐЕ] [ШÐБЛОÐ…]" @@ -13744,6 +13848,9 @@ msgstr "" msgid "write index in this format" msgstr "запиÑване на индекÑа в този формат" +msgid "report on-disk index format version" +msgstr "извеждане на верÑиÑта на форма̀та на индекÑа на диÑка" + msgid "enable or disable split index" msgstr "включване или изключване на разделÑнето на индекÑа" @@ -13769,6 +13876,14 @@ msgstr "отбелÑзване на файловете, че може да Ñе msgid "clear fsmonitor valid bit" msgstr "изчиÑтване на флага за Ñледенето чрез файловата ÑиÑтема" +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "верÑÐ¸Ñ Ð½Ð° индекÑ: бе %d, променена на %d" + msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -13868,7 +13983,7 @@ msgid "interrupt transfer after <n> seconds of inactivity" msgstr "транÑферът да Ñе преуÑтанови Ñлед този БРОЙ Ñекунди" msgid "git verify-commit [-v | --verbose] [--raw] <commit>..." -msgstr "git verify-commit [-v | --verbose] [--raw] ПОДÐÐ’ÐÐЕ…" +msgstr "git verify-commit [-v|--verbose] [--raw] ПОДÐÐ’ÐÐЕ…" msgid "print commit contents" msgstr "извеждане на Ñъдържанието на подаването" @@ -13877,7 +13992,7 @@ msgid "print raw gpg status output" msgstr "извеждане на Ð½ÐµÐ¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐµÐ½Ð¸Ñ Ð¸Ð·Ñ…Ð¾Ð´ от ÑÑŠÑтоÑнието на „gpg“" msgid "git verify-pack [-v | --verbose] [-s | --stat-only] [--] <pack>.idx..." -msgstr "git verify-pack [-v | --verbose] [-s | --stat-only] [--] ПÐКЕТ.idx…" +msgstr "git verify-pack [-v|--verbose] [-s|--stat-only] [--] ПÐКЕТ.idx…" msgid "verbose" msgstr "извеждане на подробна информациÑ" @@ -13886,20 +14001,20 @@ msgid "show statistics only" msgstr "извеждане Ñамо на ÑтатиÑтиката" msgid "git verify-tag [-v | --verbose] [--format=<format>] [--raw] <tag>..." -msgstr "git verify-tag [-v | --verbose] [--format=ФОРМÐТ] [--raw] ЕТИКЕТ…" +msgstr "git verify-tag [-v|--verbose] [--format=ФОРМÐТ] [--raw] ЕТИКЕТ…" msgid "print tag contents" msgstr "извеждане на Ñъдържанието на ЕТИКЕТи" msgid "" "git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]]\n" -" [-b <new-branch>] <path> [<commit-ish>]" +" [--orphan] [(-b | -B) <new-branch>] <path> [<commit-ish>]" msgstr "" "git worktree add [-f] [--detach] [--checkout] [--lock [--reason ÐИЗ]]\n" -" [-b ÐОВ_КЛОÐ] ПЪТ [УКÐЗÐТЕЛ_КЪМ_ПОДÐÐ’ÐÐЕ]" +" [--orphan] [(-b|-B) ÐОВ_КЛОÐ] ПЪТ [УКÐЗÐТЕЛ_КЪМ_ПОДÐÐ’ÐÐЕ]" msgid "git worktree list [-v | --porcelain [-z]]" -msgstr "git worktree list [-v | --porcelain [-z]]" +msgstr "git worktree list [-v|--porcelain [-z]]" msgid "git worktree lock [--reason <string>] <worktree>" msgstr "git worktree lock [--reason ПРИЧИÐÐ] ФОРМÐТ" @@ -13919,6 +14034,37 @@ msgstr "git worktree repair [ПЪТ…]" msgid "git worktree unlock <worktree>" msgstr "git worktree unlock ДЪРВО" +msgid "No possible source branch, inferring '--orphan'" +msgstr "ЛипÑва клон-източник, затова Ñе приема „--orphan“" + +#, c-format +msgid "" +"If you meant to create a worktree containing a new unborn branch\n" +"(branch with no commits) for this repository, you can do so\n" +"using the --orphan flag:\n" +"\n" +" git worktree add --orphan -b %s %s\n" +msgstr "" +"За да Ñъздадете работно дърво за това хранилище\n" +"Ñ Ð½Ð¾Ð² неродѐн клон — който нÑма дори и начално подаване,\n" +"ползвайте опциÑта „--orphan“:\n" +"\n" +" git worktree add --orphan -b %s %s\n" + +#, c-format +msgid "" +"If you meant to create a worktree containing a new unborn branch\n" +"(branch with no commits) for this repository, you can do so\n" +"using the --orphan flag:\n" +"\n" +" git worktree add --orphan %s\n" +msgstr "" +"За да Ñъздадете работно дърво за това хранилище\n" +"Ñ Ð½Ð¾Ð² неродѐн клон — който нÑма дори и начално подаване,\n" +"ползвайте опциÑта „--orphan“:\n" +"\n" +" git worktree add --orphan %s\n" + #, c-format msgid "Removing %s/%s: %s" msgstr "Изтриване на „%s/%s“: %s" @@ -13977,6 +14123,10 @@ msgid "initializing" msgstr "инициализациÑ" #, c-format +msgid "could not find created worktree '%s'" +msgstr "Ñъздаденото в „%s“ работно дърво липÑва" + +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "ПриготвÑне на работното дърво (нов клон „%s“)" @@ -13991,9 +14141,33 @@ msgid "Preparing worktree (checking out '%s')" msgstr "ПриготвÑне на работното дърво (изтеглÑне на „%s“)" #, c-format +msgid "unreachable: invalid reference: %s" +msgstr "недоÑтижим обект: неправилен указател: %s" + +#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "ПодготвÑне на работно дърво (указателÑÑ‚ „HEAD“ не Ñвързан: %s)" +#, c-format +msgid "" +"HEAD points to an invalid (or orphaned) reference.\n" +"HEAD path: '%s'\n" +"HEAD contents: '%s'" +msgstr "" +"HEAD Ñочи към неправилен или неродѐн указател.\n" +"HEAD path: „%s“\n" +"HEAD contents: „%s“" + +msgid "" +"No local or remote refs exist despite at least one remote\n" +"present, stopping; use 'add -f' to override or fetch a remote first" +msgstr "" +"Ðе ÑъщеÑтвуват никакви локални или отдалечени указатели, въпреки че има\n" +"поне едно Ñледено хранилище. Работата Ñпира.\n" +"Ползвайте комбинациÑта „add -f“ за принудително дейÑтвие или първо " +"доÑтавете\n" +"обектите от отдалеченото хранилище" + msgid "checkout <branch> even if already checked out in other worktree" msgstr "ИзтеглÑне КЛОÐа, дори и да е изтеглен в друго работно дърво" @@ -14003,6 +14177,9 @@ msgstr "Ñъздаване на нов клон" msgid "create or reset a branch" msgstr "Ñъздаване или занулÑване на клони" +msgid "create unborn branch" +msgstr "Ñъздаване на неродѐн клон" + msgid "populate the new working tree" msgstr "подготвÑне на новото работно дърво" @@ -14022,6 +14199,10 @@ msgstr "опит за напаÑване на името на Ð½Ð¾Ð²Ð¸Ñ ÐºÐ»Ð¾Ð msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "опциите „%s“, „%s“ и „%s“ Ñа неÑъвмеÑтими" +#, c-format +msgid "option '%s' and commit-ish cannot be used together" +msgstr "опциите „%s“ и указателите към Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ñа неÑъвмеÑтими" + msgid "added with --lock" msgstr "добавена Ñ â€ž--lock“" @@ -14258,6 +14439,14 @@ msgid_plural "The bundle requires these %<PRIuMAX> refs:" msgstr[0] "Пратката изиÑква ÑÐ»ÐµÐ´Ð½Ð¸Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»:" msgstr[1] "Пратката изиÑква Ñледните %<PRIuMAX> указатели:" +#, c-format +msgid "The bundle uses this hash algorithm: %s" +msgstr "Пратката ползва ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð°Ð»Ð³Ð¾Ñ€Ð¸Ñ‚ÑŠÐ¼ за контролни Ñуми „%s“" + +#, c-format +msgid "The bundle uses this filter: %s" +msgstr "Пратката изиÑква ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ñ„Ð¸Ð»Ñ‚ÑŠÑ€: %s" + msgid "unable to dup bundle descriptor" msgstr "неуÑпешно дублиране на деÑкриптора на пратката Ñ â€ždup“" @@ -14294,6 +14483,10 @@ msgid "terminating chunk id appears earlier than expected" msgstr "идентификаторът за краен Ð¾Ñ‚ÐºÑŠÑ Ñе ÑвÑва по-рано от очакваното" #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "откъÑÑŠÑ‚ Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€ %<PRIx32> не е подравнен по %d-байта" + +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "неправилно отмеÑтване на откъÑ/и %<PRIx64> и %<PRIx64>" @@ -14347,9 +14540,9 @@ msgstr "Събиране на Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° Ð¿Ð¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»Ñ Ð msgid "Move objects and refs by archive" msgstr "МеÑтене на обекти и указатели по архиви" -msgid "Provide content or type and size information for repository objects" +msgid "Provide contents or details of repository objects" msgstr "" -"ПредоÑтавÑне на Ñъдържанието или вида и размерите на обекти от хранилище" +"ПредоÑтавÑне на Ñъдържанието или друга Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð° обекти от хранилище" msgid "Display gitattributes information" msgstr "Извеждане на информациÑта за атрибутите на git (gitattributes)" @@ -14496,10 +14689,9 @@ msgstr "Извеждане на редовете напаÑващи на шабРmsgid "A portable graphical interface to Git" msgstr "Графичен Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÑŠÐ¼ Git" -msgid "Compute object ID and optionally creates a blob from a file" +msgid "Compute object ID and optionally create an object from a file" msgstr "" -"ИзчиÑлÑване на идентификатор на обект и евентуално Ñъздаване на обект-BLOB " -"от файл" +"ИзчиÑлÑване на идентификатор на обект и евентуално Ñъздаване на обект от файл" msgid "Display help information about Git" msgstr "Извеждане на помощта за Git" @@ -14646,6 +14838,11 @@ msgstr "Пакетиране на непакетираните обекти в Ñ msgid "Create, list, delete refs to replace objects" msgstr "Създаване, извеждане, изтриване на указатели за замÑна на обекти" +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "" +"ЕКСПЕРИМЕÐТÐЛÐО: прилагане на Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ð²ÑŠÑ€Ñ…Ñƒ нова база, работи и Ñ Ð³Ð¾Ð»Ð¸ " +"хранилища" + msgid "Generates a summary of pending changes" msgstr "Обобщение на предÑтоÑщите промѐни" @@ -14767,7 +14964,7 @@ msgstr "Проверка на подпиÑите GPG върху етикетит msgid "Display version information about Git" msgstr "Извеждане на верÑиÑта на Git" -msgid "Show logs with difference each commit introduces" +msgid "Show logs with differences each commit introduces" msgstr "Извеждане на журнал Ñ Ñ€Ð°Ð·Ð»Ð¸ÐºÐ¸Ñ‚Ðµ, въведени Ñ Ð²ÑÑко подаване" msgid "Manage multiple working trees" @@ -14884,6 +15081,36 @@ msgstr "ИнÑтрумент за управление на големи храРmsgid "commit-graph file is too small" msgstr "файлът за гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е твърде малък" +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "откъÑÑŠÑ‚ за разпределÑнето в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е прекалено малък" + +msgid "commit-graph fanout values out of order" +msgstr "" +"ÑтойноÑтите за Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° разпределÑне в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта не Ñа подредени" + +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "откъÑÑŠÑ‚ за търÑенето в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е прекалено малък" + +msgid "commit-graph commit data chunk is wrong size" +msgstr "" +"откъÑÑŠÑ‚ за данните за подаваниÑта в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÐµÐ½ размер" + +msgid "commit-graph generations chunk is wrong size" +msgstr "откъÑÑŠÑ‚ за поколениÑта в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÐµÐ½ размер" + +msgid "commit-graph changed-path index chunk is too small" +msgstr "" +"откъÑÑŠÑ‚ за индекÑа Ñ Ð¿Ñ€Ð¾Ð¼ÐµÌ€Ð½Ð¸ в пътищата в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е прекалено " +"малък" + +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "" +"преÑкачане на прекалено малък Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° индекÑа Ñ Ð¿Ñ€Ð¾Ð¼ÐµÌ€Ð½Ð¸ (%<PRIuMAX> < " +"%<PRIuMAX>) в пътищата в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" + #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "отпечатъкът на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта %X не Ñъвпада Ñ %X" @@ -14900,13 +15127,36 @@ msgstr "верÑиÑта на контролната Ñума на гра̀фа msgid "commit-graph file is too small to hold %u chunks" msgstr "файлът Ñ Ð³Ñ€Ð°Ì€Ñ„Ð° на подаваниÑта е твърде малък, за да Ñъдържа %u откъÑи" +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "" +"откъÑÑŠÑ‚ за разпределÑнето необходимо на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта липÑва или е " +"повреден" + +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "" +"откъÑÑŠÑ‚ за търÑенето необходимо на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта липÑва или е повреден" + +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "" +"откъÑÑŠÑ‚ за данните необходими на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта липÑва или е повреден" + msgid "commit-graph has no base graphs chunk" msgstr "базовиÑÑ‚ Ð¾Ñ‚ÐºÑŠÑ Ð»Ð¸Ð¿Ñва в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" +msgid "commit-graph base graphs chunk is too small" +msgstr "базовиÑÑ‚ Ð¾Ñ‚ÐºÑŠÑ Ð² гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е прекалено малък" + msgid "commit-graph chain does not match" msgstr "веригата на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта не Ñъвпада" #, c-format +msgid "commit count in base graph too high: %<PRIuMAX>" +msgstr "броÑÑ‚ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ð² оÑÐ½Ð¾Ð²Ð½Ð¸Ñ Ð³Ñ€Ð°Ñ„ е прекалено голÑм: %<PRIuMAX>" + +msgid "commit-graph chain file too small" +msgstr "веригата на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е твърде малка" + +#, c-format msgid "invalid commit-graph chain: line '%s' not a hash" msgstr "" "грешка във веригата на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта: ред „%s“ не е контролна Ñума" @@ -14924,8 +15174,15 @@ msgstr "подаването „%s“ не може да бъде открито msgid "commit-graph requires overflow generation data but has none" msgstr "" -"графът Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта изиÑква генериране на данни за отмеÑтването, но такива " -"липÑват" +"графът Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта изиÑква данни за прелелите поколениÑ, но такива липÑват" + +msgid "commit-graph overflow generation data is too small" +msgstr "прекалено малко данни за прелелите Ð¿Ð¾ÐºÐ¾Ð»ÐµÐ½Ð¸Ñ Ð² гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" + +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "" +"указателÑÑ‚ за допълнителните ребра в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е извън Ð¿Ð¾Ð·Ð²Ð¾Ð»ÐµÐ½Ð¸Ñ " +"диапазон" msgid "Loading known commits in commit graph" msgstr "Зареждане на познатите Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ð² гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" @@ -14969,7 +15226,8 @@ msgid "Finding extra edges in commit graph" msgstr "Откриване на още върхове в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" msgid "failed to write correct number of base graph ids" -msgstr "правилниÑÑ‚ брой на базовите идентификатори не може да Ñе запише" +msgstr "" +"правилниÑÑ‚ брой на идентификаторите в оÑÐ½Ð¾Ð²Ð½Ð¸Ñ Ð³Ñ€Ð°Ñ„ не може да Ñе запише" msgid "unable to create temporary graph layer" msgstr "не може да бъде Ñъздаден временен Ñлой за гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" @@ -14993,6 +15251,15 @@ msgstr "оÑновниÑÑ‚ файл на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта msgid "failed to rename temporary commit-graph file" msgstr "временниÑÑ‚ файл на гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта не може да бъде преименуван" +#, c-format +msgid "cannot merge graphs with %<PRIuMAX>, %<PRIuMAX> commits" +msgstr "" +"не може да Ñе ÑлеÑÑ‚ графове Ñ %<PRIuMAX> и %<PRIuMAX> Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ (Ñъответно)" + +#, c-format +msgid "cannot merge graph %s, too many commits: %<PRIuMAX>" +msgstr "графът „%s“ не може да Ñе Ñлее, прекалено много подаваниÑ: %<PRIuMAX>" + msgid "Scanning merged commits" msgstr "ТърÑене на подаваниÑта ÑÑŠÑ ÑливаниÑ" @@ -15019,16 +15286,13 @@ msgstr "" #, c-format msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u" msgstr "" -"неправилна ÑтойноÑÑ‚ за Ð¾Ñ‚ÐºÑŠÑ Ð² гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта: fanout[%d] = %u, а " -"трÑбва да е %u" +"неправилна ÑтойноÑÑ‚ за Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° разпределÑне в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта: " +"fanout[%d] = %u, а трÑбва да е %u" #, c-format msgid "failed to parse commit %s from commit-graph" msgstr "подаване „%s“ в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта не може да Ñе анализира" -msgid "Verifying commits in commit graph" -msgstr "Проверка на подаваниÑта в гра̀фа" - #, c-format msgid "failed to parse commit %s from object database for commit-graph" msgstr "" @@ -15054,20 +15318,6 @@ msgid "commit-graph parent list for commit %s terminates early" msgstr "ÑпиÑъкът Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ð¸ на „%s“ в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е прекалено къÑ" #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" -"номерът на поколението на подаване „%s“ в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е 0, а другаде " -"не е" - -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" -"номерът на поколението на подаване „%s“ в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта не е 0, а " -"другаде е" - -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "" "номерът на поколението на подаване „%s“ в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта е %<PRIuMAX> < " @@ -15080,6 +15330,17 @@ msgstr "" "%<PRIuMAX>" #, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "" +"гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта Ñъдържа както нулеви, така и ненулеви Ð¿Ð¾ÐºÐ¾Ð»ÐµÐ½Ð¸Ñ (напр. " +"подаваниÑта „%s“ и „%s“)" + +msgid "Verifying commits in commit graph" +msgstr "Проверка на подаваниÑта в гра̀фа" + +#, c-format msgid "%s %s is not a commit!" msgstr "%s %s не е подаване!" @@ -15106,6 +15367,12 @@ msgstr "" " git config advice.graftFileDeprecated false" #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "" +"подаването „%s“ приÑÑŠÑтва в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта, но липÑва в базата от данни " +"за обектите" + +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "" "Подаването „%s“ е Ñ Ð½ÐµÐ´Ð¾Ð²ÐµÑ€ÐµÐ½ Ð¿Ð¾Ð´Ð¿Ð¸Ñ Ð¾Ñ‚ GPG, който твърди, че е на „%s“." @@ -15567,10 +15834,6 @@ msgstr "указателÑÑ‚ „%s“ не Ñочи към обект-BLOB" msgid "unable to resolve config blob '%s'" msgstr "обектът-BLOB „%s“ Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¸ не може да бъде открит" -#, c-format -msgid "failed to parse %s" -msgstr "„%s“ не може да бъде анализиран" - msgid "unable to parse command-line config" msgstr "неправилни наÑтройки от ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¸Ñ Ñ€ÐµÐ´" @@ -16055,9 +16318,6 @@ msgstr "неуÑпешен Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° архива" msgid "--merge-base does not work with ranges" msgstr "опциÑта „--merge-base“ не работи Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð¸" -msgid "--merge-base only works with commits" -msgstr "опциÑта „--merge-base“ работи Ñамо Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" - msgid "unable to get HEAD" msgstr "УказателÑÑ‚ „HEAD“ не може да бъде получен" @@ -16067,6 +16327,12 @@ msgstr "липÑва база за Ñливане" msgid "multiple merge bases found" msgstr "много бази за Ñливане" +msgid "cannot compare stdin to a directory" +msgstr "ÑтандартниÑÑ‚ вход не може да Ñе Ñравни Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ" + +msgid "cannot compare a named pipe to a directory" +msgstr "именован канал не може да Ñе Ñравни Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ" + msgid "git diff --no-index [<options>] <path> <path>" msgstr "git diff --no-index [ОПЦИЯ…] ПЪТ ПЪТ" @@ -16119,6 +16385,10 @@ msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "Ðепозната ÑтойноÑÑ‚ „%s“ за наÑтройката „diff.submodule“" #, c-format +msgid "unknown value for config '%s': %s" +msgstr "непозната ÑтойноÑÑ‚ за наÑтройката „%s“: „%s“" + +#, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" @@ -16131,6 +16401,13 @@ msgid "external diff died, stopping at %s" msgstr "" "външната програма за разлики завърши неуÑпешно. Спиране на работата при „%s“" +msgid "--follow requires exactly one pathspec" +msgstr "опциÑта „--follow“ изиÑква точно един път" + +#, c-format +msgid "pathspec magic not supported by --follow: %s" +msgstr "магичеÑките пътища не Ñе поддържат от „--follow“: %s" + #, c-format msgid "options '%s', '%s', '%s', and '%s' cannot be used together" msgstr "опциите „%s“, „%s“, „%s“ и „%s“ Ñа неÑъвмеÑтими" @@ -16144,9 +16421,6 @@ msgid "" "options '%s' and '%s' cannot be used together, use '%s' with '%s' and '%s'" msgstr "опциите „%s“ и „%s“ Ñа неÑъвмеÑтими, използвайте „%s“ Ñ â€ž%s“ и „%s“" -msgid "--follow requires exactly one pathspec" -msgstr "опциÑта „--follow“ изиÑква точно един път" - #, c-format msgid "invalid --stat value: %s" msgstr "неправилна ÑтойноÑÑ‚ за „--stat“: %s" @@ -16193,14 +16467,6 @@ msgstr "неправилен аргумент за „--color-moved“: „%s“ msgid "invalid mode '%s' in --color-moved-ws" msgstr "неправилен режим „%s“ за „ --color-moved-ws“" -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"опциÑта приема Ñледните варианти за алгоритъм за разлики: „myers“ (по " -"МайерÑ), „minimal“ (минимизиране на разликите), „patience“ (паÑианÑ) и " -"„histogram“ (хиÑтограмен)" - #, c-format msgid "invalid argument to %s" msgstr "неправилен аргумент към „%s“" @@ -16244,8 +16510,8 @@ msgstr "„--stat“ във формат за четене от програма msgid "output only the last line of --stat" msgstr "извеждане Ñамо на поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ñ€ÐµÐ´ на „--stat“" -msgid "<param1,param2>..." -msgstr "ПÐÐ ÐМЕТЪР_1, ПÐÐ ÐМЕТЪР_2, …" +msgid "<param1>,<param2>..." +msgstr "ПÐÐ ÐМЕТЪР_1,ПÐÐ ÐМЕТЪР_2,…" msgid "" "output the distribution of relative amount of changes for each sub-directory" @@ -16254,8 +16520,8 @@ msgstr "извеждане на разпределението на промѐ msgid "synonym for --dirstat=cumulative" msgstr "пÑевдоним на „--dirstat=cumulative“" -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "пÑевдоним на „--dirstat=ФÐЙЛ…,ПÐÐ ÐМЕТЪР_1,ПÐÐ ÐМЕТЪР_2,…“" +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "пÑевдоним на „--dirstat=files,ПÐÐ ÐМЕТЪР_1,ПÐÐ ÐМЕТЪР_2,…“" msgid "warn if changes introduce conflict markers or whitespace errors" msgstr "" @@ -16439,12 +16705,6 @@ msgstr "разлика чрез алгоритъм за подредба катРmsgid "generate diff using the \"histogram diff\" algorithm" msgstr "разлика по хиÑÑ‚Ð¾Ð³Ñ€Ð°Ð¼Ð½Ð¸Ñ Ð°Ð»Ð³Ð¾Ñ€Ð¸Ñ‚ÑŠÐ¼" -msgid "<algorithm>" -msgstr "ÐЛГОРИТЪМ" - -msgid "choose a diff algorithm" -msgstr "избор на ÐЛГОРИТЪМа за разлики" - msgid "<text>" msgstr "ТЕКСТ" @@ -16918,16 +17178,9 @@ msgid "" " [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n" " [--config-env=<name>=<envvar>] <command> [<args>]" msgstr "" -"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n" -" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n" -" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--" -"bare]\n" -" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n" -" [--config-env=<name>=<envvar>] <command> [<args>]\n" -"git [-v | --version] [-h | --help] [-C ПЪТ] [-c ИМЕ=СТОЙÐОСТ]\n" +"git [-v|--version] [-h|--help] [-C ПЪТ] [-c ИМЕ=СТОЙÐОСТ]\n" " [--exec-path[=ПЪТ]] [--html-path] [--man-path] [--info-path]\n" -" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--" -"bare]\n" +" [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]\n" " [--git-dir=ПЪТ] [--work-tree=ПЪТ] [--namespace=ИМЕ]\n" " [--config-env=ИМЕ=ПРОМЕÐЛИВÐ_ÐÐ_СРЕДÐТÐ] КОМÐÐДР[ÐРГ…]" @@ -17513,12 +17766,12 @@ msgstr "" "ÐеуÑпешно Ñливане на подмодула „%s“, но Ñа открити множеÑтво решениÑ:\n" "%s" -msgid "Failed to execute internal merge" -msgstr "ÐеуÑпешно вътрешно Ñливане" +msgid "failed to execute internal merge" +msgstr "неуÑпешно вътрешно Ñливане" #, c-format -msgid "Unable to add %s to database" -msgstr "„%s“ не може да Ñе добави в базата Ñ Ð´Ð°Ð½Ð½Ð¸" +msgid "unable to add %s to database" +msgstr "„%s“ не може да Ñе добави в базата от данни" #, c-format msgid "Auto-merging %s" @@ -17967,7 +18220,22 @@ msgid "failed to read the cache" msgstr "кешът не може да бъде прочетен" msgid "multi-pack-index OID fanout is of the wrong size" -msgstr "неправилен размер на Ð¾Ñ‚ÐºÑŠÑ (OID fanout) на индекÑа за множеÑтво пакети" +msgstr "" +"неправилен размер на откъÑа за разпределÑнето в индекÑа за множеÑтво пакети" + +#, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"неправилна подредба на откъÑи (OID fanout): fanout[%d] = %<PRIx32> > " +"%<PRIx32> = fanout[%d]" + +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "неправилен размер на откъÑа за търÑенето в индекÑа за множеÑтво пакети" + +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "" +"неправилен размер на откъÑа за отмеÑтваниÑта в индекÑа за множеÑтво пакети" #, c-format msgid "multi-pack-index file %s is too small" @@ -17987,17 +18255,25 @@ msgstr "" "верÑиÑта на контролната Ñума на индекÑа за множеÑтво пакети %u не Ñъвпада Ñ " "%u" -msgid "multi-pack-index missing required pack-name chunk" -msgstr "липÑва Ð¾Ñ‚ÐºÑŠÑ (pack-name) от Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð° множеÑтво пакети" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "" +"откъÑÑŠÑ‚ за имена на пакети в индекÑа за множеÑтво пакети липÑва или е " +"повреден" -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "липÑва Ð¾Ñ‚ÐºÑŠÑ (OID fanout) от Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð° множеÑтво пакети" +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "" +"откъÑÑŠÑ‚ за разпределÑнето в индекÑа за множеÑтво пакети липÑва или е повреден" -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "липÑва Ð¾Ñ‚ÐºÑŠÑ (OID lookup) от Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð° множеÑтво пакети" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "откъÑÑŠÑ‚ за търÑене в Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð° множеÑтво пакети липÑва или е повреден" -msgid "multi-pack-index missing required object offsets chunk" -msgstr "липÑва Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° отмеÑтваниÑта на обекти от Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð° множеÑтво пакети" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "" +"откъÑÑŠÑ‚ за отмеÑÑ‚Ð²Ð°Ð½Ð¸Ñ Ð² Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð° множеÑтво пакети липÑва или е повреден" + +msgid "multi-pack-index pack-name chunk is too short" +msgstr "" +"откъÑÑŠÑ‚ за име на пакет в Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð° множеÑтво пакети липÑва или е повреден" #, c-format msgid "multi-pack-index pack names out of order: '%s' before '%s'" @@ -18010,11 +18286,23 @@ msgid "bad pack-int-id: %u (%u total packs)" msgstr "" "неправилен идентификатор на пакет (pack-int-id): %u (от общо %u пакети)" +msgid "MIDX does not contain the BTMP chunk" +msgstr "" +"липÑва Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° побитова маÑка във файла за индекÑа за множеÑтво пакети" + +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "пакетът за битови маÑки %<PRIu32> не може да Ñе отвори" + msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "" "индекÑÑŠÑ‚ за множеÑтво пакети Ñъдържа 64-битови отмеÑтваниÑ, но размерът на " "„off_t“ е недоÑтатъчен" +msgid "multi-pack-index large offset out of bounds" +msgstr "" +"ÑтойноÑтта на отмеÑтването в индекÑа за множеÑтво пакети е извън диапазона" + #, c-format msgid "failed to add packfile '%s'" msgstr "пакетниÑÑ‚ файл „%s“ не може да бъде добавен" @@ -18088,7 +18376,9 @@ msgid "failed to clear multi-pack-index at %s" msgstr "индекÑÑŠÑ‚ за множеÑтво пакети не може да бъде изчиÑтен при „%s“" msgid "multi-pack-index file exists, but failed to parse" -msgstr "файлът Ñ Ð¸Ð½Ð´ÐµÐºÑа за множеÑтво пакети, но не може да бъде анализиран" +msgstr "" +"файлът Ñ Ð¸Ð½Ð´ÐµÐºÑа за множеÑтво пакети ÑъщеÑтвува, но не може да бъде " +"анализиран" msgid "incorrect checksum" msgstr "неправилна Ñума за проверка" @@ -18096,13 +18386,6 @@ msgstr "неправилна Ñума за проверка" msgid "Looking for referenced packfiles" msgstr "ТърÑене на указаните пакетни файлове" -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "" -"неправилна подредба на откъÑи (OID fanout): fanout[%d] = %<PRIx32> > " -"%<PRIx32> = fanout[%d]" - msgid "the midx contains no oid" msgstr "във файла Ñ Ð¸Ð½Ð´ÐµÐºÑа за множеÑтво пакети нÑма идентификатори на обекти" @@ -18647,6 +18930,11 @@ msgstr "задължителниÑÑ‚ обратен Ð¸Ð½Ð´ÐµÐºÑ Ð»Ð¸Ð¿Ñва в msgid "could not open pack %s" msgstr "пакетът „%s“ не може да Ñе отвори" +msgid "could not determine MIDX preferred pack" +msgstr "" +"предпочитаниÑÑ‚ пакет за файла Ñ Ð¸Ð½Ð´ÐµÐºÑа за множеÑтво пакети не може да Ñе " +"определи" + #, c-format msgid "preferred pack (%s) is invalid" msgstr "предпочитаниÑÑ‚ пакет „%s“ е неправилен" @@ -18674,6 +18962,11 @@ msgstr "" "маÑка на подаване „%s“" #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "" +"пакетът не може да Ñе зареди: „%s“, преизползването на пакети Ñе изключва" + +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "обектът „%s“ липÑва в битовата маÑка на видовете" @@ -18768,6 +19061,13 @@ msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "" "неправилна Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð² Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑ Ð¿Ñ€Ð¸ %<PRIu64>: %<PRIu32> != %<PRIu32>" +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "" +"неправилен размер на Ð¾Ñ‚ÐºÑŠÑ Ð·Ð° обратен Ð¸Ð½Ð´ÐµÐºÑ Ð² индекÑа за множеÑтво пакети" + +msgid "could not determine preferred pack" +msgstr "предпочитаниÑÑ‚ пакет не може да Ñе определи" + msgid "cannot both write and verify reverse index" msgstr "обратниÑÑ‚ Ð¸Ð½Ð´ÐµÐºÑ Ð½Ðµ може едновременно да Ñе запиÑва и да Ñе проверÑва" @@ -18826,14 +19126,6 @@ msgid "%s requires a value" msgstr "опциÑта „%s“ изиÑква аргумент" #, c-format -msgid "%s is incompatible with %s" -msgstr "опциите „%s“ и „%s“ Ñа неÑъвмеÑтими" - -#, c-format -msgid "%s : incompatible with something else" -msgstr "опциÑта „%s“ е неÑъвмеÑтима Ñ Ð½ÐµÑ‰Ð¾" - -#, c-format msgid "%s takes no value" msgstr "опциÑта „%s“ не приема аргументи" @@ -18917,6 +19209,10 @@ msgstr " %s" msgid "-NUM" msgstr "-ЧИСЛО" +#, c-format +msgid "opposite of --no-%s" +msgstr "обратното на „--no-%s“" + msgid "expiry-date" msgstr "период на валидноÑÑ‚/запазване" @@ -18948,6 +19244,14 @@ msgstr "" "знак „NUL“" #, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "неправилна булева ÑтойноÑÑ‚ „%s“ за „%s“" + +#, c-format +msgid "failed to parse %s" +msgstr "„%s“ не може да бъде анализиран" + +#, c-format msgid "Could not make %s writable by group" msgstr "Ðе може да Ñе дадат права̀ за Ð·Ð°Ð¿Ð¸Ñ Ð² директориÑта „%s“ на групата" @@ -18995,6 +19299,10 @@ msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s: опциите „literal“ и „glob“ Ñа неÑъвмеÑтими" #, c-format +msgid "'%s' is outside the directory tree" +msgstr "„%s“ е извън дървото на директориите" + +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s: „%s“ е извън хранилището при „%s“" @@ -19126,6 +19434,13 @@ msgid "could not parse log for '%s'" msgstr "журналът Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта на „%s“ не може да бъде анализиран" #, c-format +msgid "invalid extra cruft tip: '%s'" +msgstr "неправилен ненужен връх: „%s“" + +msgid "unable to enumerate additional recent objects" +msgstr "допълнителните Ñкорошни обекти не може да Ñе изброÑÑ‚" + +#, c-format msgid "will not add file alias '%s' ('%s' already exists in index)" msgstr "" "нÑма да бъде добавен пÑевдоним за файл „%s“ („%s“ вече ÑъщеÑтвува в индекÑа)" @@ -19148,10 +19463,6 @@ msgid "unable to add '%s' to index" msgstr "„%s“ не може да Ñе добави в индекÑа" #, c-format -msgid "unable to stat '%s'" -msgstr "„stat“ не може да Ñе изпълни върху „%s“" - -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "„%s“ ÑъщеÑтвува и като файл, и като директориÑ" @@ -19269,10 +19580,6 @@ msgid "failed to convert to a sparse-index" msgstr "индекÑÑŠÑ‚ не може да бъде превърнат в чаÑтичен" #, c-format -msgid "could not stat '%s'" -msgstr "неуÑпешно изпълнение на „stat“ върху „%s“" - -#, c-format msgid "unable to open git dir: %s" msgstr "не може да Ñе отвори директориÑта на git: %s" @@ -19288,6 +19595,14 @@ msgstr "права̀та за доÑтъп до „%s“ не може да бъ msgid "%s: cannot drop to stage #0" msgstr "%s: не може да Ñе премине към етап â„–0" +#, c-format +msgid "unexpected diff status %c" +msgstr "неочакван изходен код при генериране на разлика: %c" + +#, c-format +msgid "remove '%s'\n" +msgstr "изтриване на „%s“\n" + msgid "" "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --" "continue'.\n" @@ -19337,7 +19652,7 @@ msgstr "" " e, edit ПОДÐÐ’ÐÐЕ — прилагане на подаването и Ñпиране при него за още " "промѐни\n" " s, squash ПОДÐÐ’ÐÐЕ — вкарване на подаването в предходното му\n" -" f, fixup [-C | -c] ПОДÐÐ’ÐÐЕ\n" +" f, fixup [-C|-c] ПОДÐÐ’ÐÐЕ\n" " — вкарване на подаването в предходното му, без ÑмÑна на\n" " Ñъобщението. С „-C“ Ñе използва Ñамо Ñъобщението на\n" " наÑтоÑщото, а Ñ â€ž-c“ оÑвен това Ñе Ð¾Ñ‚Ð²Ð°Ñ€Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€ÑŠÑ‚\n" @@ -19349,7 +19664,7 @@ msgstr "" " d, drop ПОДÐÐ’ÐÐЕ — преÑкачане на подаването\n" " l, label ЕТИКЕТ — задаване на етикет на указаното от HEAD\n" " t, reset ЕТИКЕТ — занулÑване на HEAD към ЕТИКЕТа\n" -" m, merge [-C ПОДÐÐ’ÐÐЕ | -c ПОДÐÐ’ÐÐЕ] ЕТИКЕТ [# ЕДИÐ_РЕД]\n" +" m, merge [-C ПОДÐÐ’ÐÐЕ|-c ПОДÐÐ’ÐÐЕ] ЕТИКЕТ [# ЕДИÐ_РЕД]\n" " — Ñъздаване на подаване ÑÑŠÑ Ñливане ÑÑŠÑ Ñъобщението от\n" " първоначалното подаване (или Ñъобщението от ЕДИÐ_РЕД,\n" " ако не е зададено подаване ÑÑŠÑ Ñливане. С опциÑта\n" @@ -19490,6 +19805,22 @@ msgid "positive value expected contents:lines=%s" msgstr "очаква Ñе положителна ÑтойноÑÑ‚ за „contents:lines=%s“" #, c-format +msgid "argument expected for %s" +msgstr "„%s“ изиÑква аргумент" + +#, c-format +msgid "positive value expected %s=%s" +msgstr "очаква Ñе положителна ÑтойноÑÑ‚ за „%s=%s“" + +#, c-format +msgid "cannot fully parse %s=%s" +msgstr "„%s=%s“ не може да Ñе анализира докрай" + +#, c-format +msgid "value expected %s=" +msgstr "очаква Ñе ÑтойноÑÑ‚ за „%s=“" + +#, c-format msgid "positive value expected '%s' in %%(%s)" msgstr "очаква Ñе положителна ÑтойноÑÑ‚ за „%s“ в %%(%s)" @@ -19563,6 +19894,9 @@ msgid "--format=%.*s cannot be used with --python, --shell, --tcl" msgstr "" "опциÑта „--format=%.*s“ е неÑъвмеÑтима Ñ â€ž--python“, „--shell“, „--tcl“" +msgid "failed to run 'describe'" +msgstr "неуÑпешно изпълнение на „describe“" + #, c-format msgid "(no branch, rebasing %s)" msgstr "(извън клон, пребазиране на „%s“)" @@ -19624,6 +19958,9 @@ msgstr "КЛЮЧ" msgid "field name to sort on" msgstr "име на полето, по което да е подредбата" +msgid "exclude refs which match pattern" +msgstr "преÑкачана на указателите напаÑващи на ШÐБЛОÐа" + #, c-format msgid "not a reflog: %s" msgstr "„%s“ не е журнал Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" @@ -19670,7 +20007,7 @@ msgstr "неправилно име на клон: „%s = %s“" #, c-format msgid "ignoring dangling symref %s" -msgstr "игнориране на указател на обект извън клон „%s“" +msgstr "игнориране на файл Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ» на обект извън клон „%s“" #, c-format msgid "log for ref %s has gap after %s" @@ -19711,10 +20048,6 @@ msgid "cannot process '%s' and '%s' at the same time" msgstr "невъзможно е едновременно да Ñе обработват „%s“ и „%s“" #, c-format -msgid "could not remove reference %s" -msgstr "УказателÑÑ‚ „%s“ не може да бъде изтрит" - -#, c-format msgid "could not delete reference %s: %s" msgstr "УказателÑÑ‚ „%s“ не може да бъде изтрит: %s" @@ -20074,7 +20407,8 @@ msgstr[1] "" "ТекущиÑÑ‚ клон Ñе е раздалечил от „%s“,\n" "двата имат Ñъответно по %d и %d неÑъвпадащи подаваниÑ.\n" -msgid " (use \"git pull\" to merge the remote branch into yours)\n" +msgid "" +" (use \"git pull\" if you want to integrate the remote branch with yours)\n" msgstr " (Ñлейте Ð¾Ñ‚Ð´Ð°Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½ в Ð»Ð¾ÐºÐ°Ð»Ð½Ð¸Ñ Ñ‡Ñ€ÐµÐ· „git pull“)\n" #, c-format @@ -20193,6 +20527,10 @@ msgstr "подаването „%s“ към опциÑта „--ancestry-path†msgid "--unpacked=<packfile> no longer supported" msgstr "опциÑта „--unpacked=ПÐКЕТЕÐ_ФÐЙЛ“ вече не Ñе поддържа" +#, c-format +msgid "invalid option '%s' in --stdin mode" +msgstr "опциите „%s“ и „--stdin“ Ñа неÑъвмеÑтими" + msgid "your current branch appears to be broken" msgstr "ТекущиÑÑ‚ клон е повреден" @@ -20281,8 +20619,15 @@ msgstr "при клониране да Ñе Ñъздава пълна работ msgid "only download metadata for the branch that will be checked out" msgstr "да Ñе ÑвалÑÑ‚ метаданните Ñамо за изтеглÑÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½" -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [ОПЦИЯ…] [--] ХРÐÐИЛИЩЕ [ДИРЕКТОРИЯ]" +msgid "create repository within 'src' directory" +msgstr "Ñъздаване на хранилище в Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ â€žsrc“" + +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch ОСÐОВЕÐ_КЛОÐ] [--full-clone]\n" +" [--[no-]src] ÐДРЕС [ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20323,7 +20668,7 @@ msgid "reconfigure all registered enlistments" msgstr "пренаÑтройване на вÑички зачиÑлени директории" msgid "scalar reconfigure [--all | <enlistment>]" -msgstr "scalar reconfigure [--all | ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]" +msgstr "scalar reconfigure [--all|ЗÐЧИСЛЕÐÐ_ДИРЕКТОРИЯ]" msgid "--all or <enlistment>, but not both" msgstr "опциÑта „--all“ и указването на зачиÑлена Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ Ñа ÑъвмеÑтими" @@ -20333,12 +20678,29 @@ msgid "could not remove stale scalar.repo '%s'" msgstr "оÑтарÑлото Ñкаларно хранилище (scalar.repo) „%s“ не може да Ñе изтрие" #, c-format -msgid "removing stale scalar.repo '%s'" +msgid "removed stale scalar.repo '%s'" msgstr "изтриване на оÑтарÑлото Ñкаларно хранилище (scalar.repo) „%s“" #, c-format -msgid "git repository gone in '%s'" -msgstr "вече нÑма хранилище на git в „%s“" +msgid "repository at '%s' has different owner" +msgstr "хранилището „%s“ Ñе притежава от друг" + +#, c-format +msgid "repository at '%s' has a format issue" +msgstr "хранилището в „%s“ е Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÐµÐ½ формат" + +#, c-format +msgid "repository not found in '%s'" +msgstr "в „%s“ липÑва хранилище на git" + +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"за да преуÑтановите региÑтрациÑта на хранилището в Scalar, изпълнете\n" +"\n" +" git config --global --unset --fixed-value scalar.repo \"%s\"" msgid "" "scalar run <task> [<enlistment>]\n" @@ -20367,7 +20729,7 @@ msgid "include Git's build options" msgstr "включване и на опциите за компилиране на git" msgid "scalar verbose [-v | --verbose] [--build-options]" -msgstr "scalar verbose [-v | --verbose] [--build-options]" +msgstr "scalar verbose [-v|--verbose] [--build-options]" msgid "-C requires a <directory>" msgstr "„-C“ изиÑква ДИРЕКТОРИЯ" @@ -20775,10 +21137,6 @@ msgid "%s: cannot parse parent commit %s" msgstr "%s: неразпозната ÑтойноÑÑ‚ за родителÑкото подаване „%s“" #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "„%s“ не може да Ñе преименува на „%s“" - -#, c-format msgid "could not revert %s... %s" msgstr "подаването „%s“… не може да бъде отменено: „%s“" @@ -20873,14 +21231,14 @@ msgstr "в момента вече Ñе извършва отмÑна на поР#, c-format msgid "try \"git revert (--continue | %s--abort | --quit)\"" -msgstr "използвайте „git revert (--continue | %s--abort | --quit)“" +msgstr "използвайте „git revert (--continue|%s--abort|--quit)“" msgid "cherry-pick is already in progress" msgstr "в момента вече Ñе извършва отбиране на подаваниÑ" #, c-format msgid "try \"git cherry-pick (--continue | %s--abort | --quit)\"" -msgstr "използвайте „git cherry-pick (--continue | %s--abort | --quit)“" +msgstr "използвайте „git cherry-pick (--continue|%s--abort|--quit)“" #, c-format msgid "could not create sequencer directory '%s'" @@ -21114,6 +21472,9 @@ msgstr "Конфликти при прилагането на автоматич msgid "Autostash exists; creating a new stash entry." msgstr "Вече има Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° автоматично Ñкатано, затова Ñе Ñъздава нов запиÑ." +msgid "autostash reference is a symref" +msgstr "указателÑÑ‚ за автоматично Ñкатано e файл Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»" + msgid "could not detach HEAD" msgstr "указателÑÑ‚ „HEAD“ не може да Ñе отдели" @@ -21148,14 +21509,14 @@ msgstr "" " git rebase --continue\n" #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "Пребазиране (%d/%d)%s" - -#, c-format msgid "Stopped at %s... %.*s\n" msgstr "Спиране при „%s“… %.*s\n" #, c-format +msgid "Rebasing (%d/%d)%s" +msgstr "Пребазиране (%d/%d)%s" + +#, c-format msgid "unknown command %d" msgstr "непозната команда %d" @@ -21402,6 +21763,85 @@ msgid "setsid failed" msgstr "неуÑпешно изпълнение на „setsid“" #, c-format +msgid "cannot stat template '%s'" +msgstr "не може да Ñе получи Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ñ‡Ñ€ÐµÐ· „stat“ за шаблона „%s“" + +#, c-format +msgid "cannot opendir '%s'" +msgstr "директориÑта „%s“ не може да бъде отворена" + +#, c-format +msgid "cannot readlink '%s'" +msgstr "връзката „%s“ не може да бъде прочетена" + +#, c-format +msgid "cannot symlink '%s' '%s'" +msgstr "не може да Ñе Ñъздаде Ñимволна връзка „%s“ в „%s“" + +#, c-format +msgid "cannot copy '%s' to '%s'" +msgstr "„%s“ не може да Ñе копира в „%s“" + +#, c-format +msgid "ignoring template %s" +msgstr "игнориране на шаблона „%s“" + +#, c-format +msgid "templates not found in %s" +msgstr "нÑма шаблони в „%s“" + +#, c-format +msgid "not copying templates from '%s': %s" +msgstr "шаблоните нÑма да бъдат копирани от „%s“: „%s“" + +#, c-format +msgid "invalid initial branch name: '%s'" +msgstr "неправилно име на Ð¿ÑŠÑ€Ð²Ð¾Ð½Ð°Ñ‡Ð°Ð»Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½: „%s“" + +#, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "re-init: „--initial-branch=%s“ Ñе пропуÑка" + +#, c-format +msgid "unable to handle file type %d" +msgstr "файлове от вид %d не Ñе поддържат" + +#, c-format +msgid "unable to move %s to %s" +msgstr "„%s“ не може да Ñе премеÑти в „%s“" + +msgid "attempt to reinitialize repository with different hash" +msgstr "" +"опит за занулÑване на хранилището и инициализиране Ñ Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð½Ð° контролна Ñума" + +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "" +"опит за занулÑване на хранилището и инициализиране Ñ Ñ€Ð°Ð·Ð»Ð¸Ñ‡ÐµÐ½ формат на " +"ÑъхранÑване" + +#, c-format +msgid "%s already exists" +msgstr "ДиректориÑта „%s“ вече ÑъщеÑтвува" + +#, c-format +msgid "Reinitialized existing shared Git repository in %s%s\n" +msgstr "" +"Инициализиране наново на ÑъщеÑтвуващо, Ñподелено хранилище на Git в „%s%s“\n" + +#, c-format +msgid "Reinitialized existing Git repository in %s%s\n" +msgstr "Инициализиране наново на ÑъщеÑтвуващо хранилище на Git в „%s%s“\n" + +#, c-format +msgid "Initialized empty shared Git repository in %s%s\n" +msgstr "Инициализиране на празно, Ñподелено хранилище на Git в „%s%s“\n" + +#, c-format +msgid "Initialized empty Git repository in %s%s\n" +msgstr "Инициализиране на празно хранилище на Git в „%s%s“\n" + +#, c-format msgid "index entry is a directory, but not sparse (%08x)" msgstr "обектът в индекÑа е директориÑ, но не чаÑтично изтеглена (%08x)" @@ -21655,12 +22095,6 @@ msgstr "" "какъв брой запиÑи в кеша на обектите-дървета да Ñе отбележат като невалидни " "(Ñтандартно е 0)" -msgid "unhandled options" -msgstr "неподдържани опции" - -msgid "error preparing revisions" -msgstr "грешка при подготовката на верÑии" - #, c-format msgid "commit %s is not marked reachable" msgstr "подаването „%s“ не е отбелÑзано като доÑтижимо" @@ -21817,9 +22251,6 @@ msgstr "протоколът не поддържа задаването на Ð¿Ñ msgid "invalid remote service path" msgstr "неправилен път на отдалечената уÑлуга" -msgid "operation not supported by protocol" -msgstr "опциÑта не Ñе поддържа от протокола" - #, c-format msgid "can't connect to subservice %s" msgstr "неуÑпешно Ñвързване към подуÑлугата „%s“" @@ -21955,10 +22386,6 @@ msgid "support for protocol v2 not implemented yet" msgstr "протокол верÑÐ¸Ñ 2 вÑе още не Ñе поддържа" #, c-format -msgid "unknown value for config '%s': %s" -msgstr "непозната ÑтойноÑÑ‚ за наÑтройката „%s“: „%s“" - -#, c-format msgid "transport '%s' not allowed" msgstr "преноÑÑŠÑ‚ по „%s“ не е позволен" @@ -22011,6 +22438,9 @@ msgstr "" "ÑпъÑъкът Ñ Ð°Ð´Ñ€ÐµÑи на пратки обÑвени за налични от Ñървъра не може да Ñе " "получи " +msgid "operation not supported by protocol" +msgstr "опциÑта не Ñе поддържа от протокола" + msgid "too-short tree object" msgstr "прекалено кратък обект-дърво" @@ -22399,6 +22829,9 @@ msgstr "нÑма доÑтъп до „%s“" msgid "unable to get current working directory" msgstr "текущата работна Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ðµ недоÑтъпна" +msgid "unable to get random bytes" +msgstr "не може да Ñе получат Ñлучайни байтове" + msgid "Unmerged paths:" msgstr "ÐеÑлети пътища:" @@ -22851,6 +23284,10 @@ msgstr "оÑвен това в индекÑа има неподадени про msgid "cannot %s: Your index contains uncommitted changes." msgstr "не може да извършите „%s“, защото в индекÑа има неподадени промѐни." +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "непознат Ñтил „%s“ за „%s“" + msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" @@ -23044,13 +23481,13 @@ msgstr "" "Изтрийте вÑичко, ако не иÑкате да изпратите обобщаващо пиÑмо.\n" #, perl-format -msgid "Failed to open %s: %s" -msgstr "„%s“ не може да Ñе отвори: %s" - -#, perl-format msgid "Failed to open %s.final: %s" msgstr "„%s.final“ не може да Ñе отвори: %s" +#, perl-format +msgid "Failed to open %s: %s" +msgstr "„%s“ не може да Ñе отвори: %s" + msgid "Summary email is empty, skipping it\n" msgstr "Обобщаващото пиÑмо е празно и Ñе преÑкача\n" @@ -1,7 +1,7 @@ # Catalan translations for Git. # This file is distributed under the same license as the Git package. # Alex Henrie <alexhenrie24@gmail.com>, 2014-2016. -# Jordi Mas i Hernà ndez <jmas@softcatala.org>, 2016-2023 +# Jordi Mas i Hernà ndez <jmas@softcatala.org>, 2016-2024 # # Terminologia # @@ -14,6 +14,7 @@ # bundle | farcell # check out | agafar # chunk | fragment +# commit | comissió # cover letter | carta de presentació # cruft | superflu # delta | diferència @@ -28,6 +29,7 @@ # hint | consell # hook | lligam # hunk | tros +# multi-pack-index | Ãndex multipaquet # not supported | no està admès # pull | baixar # push | pujar @@ -54,6 +56,7 @@ # Anglès | Català # -----------------+--------------------------------- # blame | «blame» +# fanout | «fanout» # HEAD | HEAD (f, la branca actual) - (no s'apostrofa) # cherry pick | «cherry pick» # promisor | «promisor» @@ -68,14 +71,14 @@ # # Criteris # - Mantingueu en anglès les referències a seccions de la documentació, ja que no està traduïda. -# - Usem la convenció valenciana per a «per / per a», que inclou l'ús de «per a» davant d'infintiu +# - Usem la convenció valenciana per a «per / per a», que inclou l'ús de «per a» davant d'infinitiu # msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-16 18:22+0200\n" -"PO-Revision-Date: 2023-08-16 19:00-0600\n" +"POT-Creation-Date: 2024-02-16 07:14+0100\n" +"PO-Revision-Date: 2024-02-16 07:16+0100\n" "Last-Translator: Jordi Mas i Hernà ndez <jmas@softcatala.org>\n" "Language-Team: Catalan\n" "Language: ca\n" @@ -1502,6 +1505,10 @@ msgid "Unexpected option --output" msgstr "Opció inesperada --output" #, c-format +msgid "extra command line parameter '%s'" +msgstr "parà metre extra de la lÃnia d'ordres «%s»" + +#, c-format msgid "Unknown archive format '%s'" msgstr "Format d'arxiu desconegut «%s»" @@ -1537,16 +1544,24 @@ msgstr "no es pot fer fstat gitattributes al fitxer «%s»" #, c-format msgid "ignoring overly large gitattributes file '%s'" -msgstr "s'ignorarà el fitxer «%s» gitattributes per ser massa gran" +msgstr "s'ignorarà el fitxer «%s» gitattributes per a ser massa gran" #, c-format msgid "ignoring overly large gitattributes blob '%s'" -msgstr "s'ignorarà el blob «%s» gitattributes per ser massa gran" +msgstr "s'ignorarà el blob «%s» gitattributes per a ser massa gran" msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "--attr-source incorrecte o GIT_ATTR_SOURCE" #, c-format +msgid "unable to stat '%s'" +msgstr "no s'ha pogut fer «stat» a «%s»" + +#, c-format +msgid "unable to read %s" +msgstr "no s'ha pogut llegir %s" + +#, c-format msgid "Badly quoted content in file '%s': %s" msgstr "Comentari amb cometes errònies en el fitxer «%s»: %s" @@ -1835,8 +1850,8 @@ msgid "submodule '%s': cannot create branch '%s'" msgstr "submòdul «%s»: no es pot crear la branca: «%s»" #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "«%s» ja s'ha agafat a «%s»" +msgid "'%s' is already used by worktree at '%s'" +msgstr "«%s» ja s'utilitza en l'arbre de treball a «%s»" msgid "git add [<options>] [--] <pathspec>..." msgstr "git add [<opcions>] [--] <especificació-de-camÃ>..." @@ -1855,25 +1870,22 @@ msgstr "" "s'ha eliminat la configuració add.interactive.useBuiltin\n" "Per a més detalls, vegeu la seva entrada a «git help config»." -msgid "Could not read the index" -msgstr "No s'ha pogut llegir l'Ãndex" - -msgid "Could not write patch" -msgstr "No s'ha pogut escriure el pedaç" +msgid "could not read the index" +msgstr "no s'ha pogut llegir l'Ãndex" msgid "editing patch failed" msgstr "l'edició del pedaç ha fallat" #, c-format -msgid "Could not stat '%s'" -msgstr "No s'ha pogut fer stat a «%s»" +msgid "could not stat '%s'" +msgstr "no s'ha pogut fer stat a «%s»" -msgid "Empty patch. Aborted." -msgstr "El pedaç és buit. S'ha avortat." +msgid "empty patch. aborted" +msgstr "pedaç buit. interromput" #, c-format -msgid "Could not apply '%s'" -msgstr "No s'ha pogut aplicar «%s»" +msgid "could not apply '%s'" +msgstr "no s'ha pogut aplicar «%s»" msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" @@ -2002,6 +2014,9 @@ msgstr "" msgid "index file corrupt" msgstr "fitxer d'Ãndex malmès" +msgid "unable to write new index file" +msgstr "no s'ha pogut escriure un fitxer d'Ãndex nou" + #, c-format msgid "bad action '%s' for '%s'" msgstr "acció «%s» incorrecta per a «%s»" @@ -2210,9 +2225,6 @@ msgstr "" "Podeu executar «git rm» en un fitxer per a acceptar «suprimit per ells» pel " "fitxer." -msgid "unable to write new index file" -msgstr "no s'ha pogut escriure un fitxer d'Ãndex nou" - #, c-format msgid "Could not parse object '%s'." msgstr "No s'ha pogut analitzar l'objecte «%s»." @@ -2231,10 +2243,6 @@ msgstr "" msgid "failed to read '%s'" msgstr "s'ha produït un error en llegir «%s»" -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "les opcions «%s=%s» i «%s=%s» no es poden usar juntes" - msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<opcions>] [(<bústia> | <directori-de-correu>)...]" @@ -2387,10 +2395,10 @@ msgid "git archive: expected a flush" msgstr "git archive: s'esperava una neteja" msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgid "git bisect (good|bad) [<rev>...]" @@ -2405,8 +2413,8 @@ msgstr "git bisect reset [<comissió>]" msgid "git bisect replay <logfile>" msgstr "git bisect replay <logfile>" -msgid "git bisect run <cmd>..." -msgstr "git bisect run <ordre>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <cmd> [<arg>...]" #, c-format msgid "cannot open file '%s' in mode '%s'" @@ -2834,46 +2842,45 @@ msgstr "git branch [<opcions>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" -"s'està suprimint la branca «%s» que s'ha\n" -" fusionat a «%s», però encara no\n" -" s'ha fusionat a HEAD." +"s'està suprimint la branca «%s» que s'ha fusionat a\n" +" «%s», però encara no s'ha fusionat a HEAD" #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" -"no s'està suprimint la branca «%s» que encara no\n" -" s'ha fusionat a «%s», encara que està \n" -" fusionada a HEAD." +"no s'està suprimint la branca «%s» que encara no s'ha fusionat a\n" +" «%s», encara que s'hagi fusionat a HEAD" #, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "No s'ha pogut trobar l'objecte de comissió de «%s»" +msgid "couldn't look up commit object for '%s'" +msgstr "no s'ha pogut cercar l'objecte de comissió per a «%s»" #, 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 "" -"La branca «%s» no està totalment fusionada.\n" -"Si esteu segur que la voleu suprimir, executeu «git branch -D %s»." +msgid "the branch '%s' is not fully merged" +msgstr "la branca «%s» no està completament fusionada" + +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" +msgstr "Si esteu segur que voleu suprimir-la, executeu «git branch -D %s»" -msgid "Update of config-file failed" -msgstr "L'actualització del fitxer de configuració ha fallat" +msgid "update of config-file failed" +msgstr "ha fallat l'actualització del fitxer de configuració" msgid "cannot use -a with -d" msgstr "no es pot usar -a amb -d" #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "No es pot suprimir la branca «%s» agafada a «%s»" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "" +"no es pot suprimir la branca «%s» utilitzada per l'arbre de treball a «%s»" #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "no s'ha trobat la branca amb seguiment remot «%s»." +msgid "remote-tracking branch '%s' not found" +msgstr "no s'ha trobat la branca de seguiment remot «%s»" #, c-format msgid "" @@ -2884,8 +2891,8 @@ msgstr "" "Us heu oblidat de --remote?" #, c-format -msgid "branch '%s' not found." -msgstr "no s'ha trobat la branca «%s»." +msgid "branch '%s' not found" +msgstr "no s'ha trobat la branca «%s»" #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" @@ -2906,56 +2913,56 @@ msgid "HEAD (%s) points outside of refs/heads/" msgstr "HEAD (%s) apunta fora de refs/heads/" #, c-format -msgid "Branch %s is being rebased at %s" -msgstr "S'està fent «rebase» en la branca %s a %s" +msgid "branch %s is being rebased at %s" +msgstr "a la branca %s se li està fent a «rebase» a %s" #, c-format -msgid "Branch %s is being bisected at %s" -msgstr "La branca %s s'està bisecant a %s" +msgid "branch %s is being bisected at %s" +msgstr "la branca %s s'està bisecant a %s" #, c-format msgid "HEAD of working tree %s is not updated" msgstr "HEAD de l'arbre de treball %s no està actualitzat" #, c-format -msgid "Invalid branch name: '%s'" -msgstr "Nom de branca no và lid: «%s»" +msgid "invalid branch name: '%s'" +msgstr "el nom de la branca no és và lid: «%s»" #, c-format -msgid "No commit on branch '%s' yet." -msgstr "Encara no hi ha cap comissió en la branca «%s»." +msgid "no commit on branch '%s' yet" +msgstr "encara no hi ha cap comissió a la branca «%s»" #, c-format -msgid "No branch named '%s'." -msgstr "No hi ha cap branca amb nom «%s»." +msgid "no branch named '%s'" +msgstr "no hi ha cap branca anomenada «%s»" -msgid "Branch rename failed" -msgstr "El canvi de nom de branca ha fallat" +msgid "branch rename failed" +msgstr "ha fallat el canvi de nom de la branca" -msgid "Branch copy failed" -msgstr "La còpia de la branca ha fallat" +msgid "branch copy failed" +msgstr "ha fallat la còpia de la branca" #, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "S'ha creat una còpia d'una branca mal anomenada «%s»" +msgid "created a copy of a misnamed branch '%s'" +msgstr "s'ha creat una còpia d'una branca mal anomenada «%s»" #, c-format -msgid "Renamed a misnamed branch '%s' away" -msgstr "S'ha canviat el nom de la branca mal anomenada «%s»" +msgid "renamed a misnamed branch '%s' away" +msgstr "s'ha canviat el nom d'una branca «%s» mal anomenada" #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "S'ha canviat el nom de la branca a %s, però HEAD no està actualitzat!" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "s'ha canviat el nom de la branca a %s, però HEAD no s'ha actualitzat" -msgid "Branch is renamed, but update of config-file failed" +msgid "branch is renamed, but update of config-file failed" msgstr "" -"La branca està canviada de nom, però l'actualització del fitxer de " -"configuració ha fallat" +"s'ha canviat el nom de la branca, però ha fallat l'actualització del fitxer " +"de configuració" -msgid "Branch is copied, but update of config-file failed" +msgid "branch is copied, but update of config-file failed" msgstr "" -"La branca està copiada, però l'actualització del fitxer de configuració ha " -"fallat" +"s'ha copiat la branca, però ha fallat l'actualització del fitxer de " +"configuració" #, c-format msgid "" @@ -3069,8 +3076,8 @@ msgstr "inclou recursivament els submòduls" msgid "format to use for the output" msgstr "format a usar en la sortida" -msgid "Failed to resolve HEAD as a valid ref." -msgstr "S'ha produït un error en resoldre HEAD com a referència và lida." +msgid "failed to resolve HEAD as a valid ref" +msgstr "no s'ha pogut resoldre HEAD com a referència và lida" msgid "HEAD not found below refs/heads!" msgstr "HEAD no trobat sota refs/heads!" @@ -3088,17 +3095,18 @@ msgstr "--recurse-submodules només es pot utilitzar per a crear branques" msgid "branch name required" msgstr "cal el nom de branca" -msgid "Cannot give description to detached HEAD" -msgstr "No es pot donar descripció a una HEAD separada" +msgid "cannot give description to detached HEAD" +msgstr "no s'ha pogut donar la descripció al HEAD separat" msgid "cannot edit description of more than one branch" msgstr "no es pot editar la descripció de més d'una branca" -msgid "cannot copy the current branch while not on any." -msgstr "no es pot copiar branca actual mentre no s'és a cap." +msgid "cannot copy the current branch while not on any" +msgstr "no es pot copiar la branca actual mentre no pertanyi a cap" -msgid "cannot rename the current branch while not on any." -msgstr "no es pot canviar el nom de la branca actual mentre no s'és a cap." +msgid "cannot rename the current branch while not on any" +msgstr "" +"no s'ha pogut canviar el nom de la branca actual mentre no pertanyi a cap" msgid "too many branches for a copy operation" msgstr "hi ha massa branques per a una operació de còpia" @@ -3111,9 +3119,9 @@ msgstr "hi ha massa arguments per a establir una nova font" #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." +"could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" -"no s'ha pogut establir la font de HEAD com a %s quan no assenyala cap branca." +"no s'ha pogut configurar la font de HEAD a %s quan no apunta a cap branca" #, c-format msgid "no such branch '%s'" @@ -3126,27 +3134,26 @@ msgstr "la branca «%s» no existeix" msgid "too many arguments to unset upstream" msgstr "hi ha massa arguments per a desassignar la font" -msgid "could not unset upstream of HEAD when it does not point to any branch." -msgstr "" -"no s'ha pogut desassignar la font de HEAD perquè no assenyala cap branca." +msgid "could not unset upstream of HEAD when it does not point to any branch" +msgstr "no s'ha pogut desassignar la font del HEAD quan no apunta a cap branca" #, c-format -msgid "Branch '%s' has no upstream information" -msgstr "La branca «%s» no té informació de font" +msgid "branch '%s' has no upstream information" +msgstr "la branca «%s» no té informació de la font" msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"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 "" -"Les opcions -a i -r a «git branch» no prenen un nom de branca.\n" -"VolÃeu usar -a|-r --list <patró>?" +"les opcions -a, i -r, a «git branch» no prenen un nom de branca.\n" +"VolÃeu utilitzar: -a|-r --list <patró>?" msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." +"'--set-upstream-to' instead" msgstr "" -"l'opció --set-upstream ja no s'admet. En lloc seu, useu «--track» o «--set-" -"upstream-to»." +"l'opció «--set-upstream» ja no és admesa. Utilitzeu en comptes «--track» o " +"«--set-upstream-to»" msgid "git version:\n" msgstr "versió de git:\n" @@ -3220,6 +3227,10 @@ msgid "specify a strftime format suffix for the filename(s)" msgstr "especifiqueu un sufix en format strftime per al nom de fitxer" #, c-format +msgid "unknown argument `%s'" +msgstr "argument desconegut «%s»" + +#, c-format msgid "could not create leading directories for '%s'" msgstr "no s'han pogut crear els directoris principals de «%s»" @@ -3326,6 +3337,13 @@ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objecte>" msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" + +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -3336,13 +3354,6 @@ msgstr "" " [--buffer] [--follow-symlinks] [--unordered]\n" " [--textconv | --filters] [-Z]" -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" - msgid "Check object existence or emit object contents" msgstr "Comprova l'existència de l'objecte o emet el contingut de l'objecte" @@ -3640,6 +3651,10 @@ msgid "'%s' or '%s' cannot be used with %s" msgstr "«%s» o «%s» no poden utilitzar-se amb %s" #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "«%s», «%s» o «%s» no es poden utilitzar en agafar un arbre" + +#, c-format msgid "path '%s' is unmerged" msgstr "el camà «%s» està sense fusionar" @@ -3891,8 +3906,8 @@ msgstr "agafa a la força (descarta qualsevol modificació local)" msgid "new-branch" msgstr "branca-nova" -msgid "new unparented branch" -msgstr "branca òrfena nova" +msgid "new unborn branch" +msgstr "branca no nascuda nova" msgid "update ignored files (default)" msgstr "actualitza els fitxers ignorats (per defecte)" @@ -4144,9 +4159,6 @@ msgstr "" "clean.requireForce és per defecte cert i ni -i, -n ni -f s'han indicat; " "refusant netejar" -msgid "-x and -X cannot be used together" -msgstr "-x i -X no es poden usar junts" - msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<opcions>] [--] <repositori> [<directori>]" @@ -4235,6 +4247,9 @@ msgstr "directori de git" msgid "separate git dir from working tree" msgstr "separa el directori de git de l'arbre de treball" +msgid "specify the reference format to use" +msgstr "especifiqueu el format de referència a usar" + msgid "key=value" msgstr "clau=valor" @@ -4354,11 +4369,9 @@ msgstr "Hi ha massa arguments." msgid "You must specify a repository to clone." msgstr "Heu d'especificar un repositori per a clonar." -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "" -"--bundle-uri és incompatible amb --depth, --shallow-since i --shallow-exclude" +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "el format d'emmagatzematge de referència «%s» és desconegut" #, c-format msgid "repository '%s' does not exist" @@ -4488,14 +4501,14 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <dir>] [--append]\n" " [--split[=<strategy>]] [--reachable | --stdin-packs | " "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgid "dir" msgstr "directori" @@ -4512,6 +4525,10 @@ msgid "Could not open commit-graph '%s'" msgstr "No s'ha pogut obrir el graf de comissions «%s»" #, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "no s'ha pogut obrir la cadena «%s» del graf de comissions" + +#, c-format msgid "unrecognized --split argument, %s" msgstr "argument --split no reconegut, %s" @@ -4709,9 +4726,6 @@ msgstr "no s'ha pogut actualitzar l'Ãndex temporal" msgid "Failed to update main cache tree" msgstr "S'ha produït un error en actualitzar l'arbre principal de memòria cau" -msgid "unable to write new_index file" -msgstr "no s'ha pogut escriure el fitxer new_index" - msgid "cannot do a partial commit during a merge." msgstr "no es pot fer una comissió parcial durant una fusió." @@ -5114,13 +5128,13 @@ msgstr "" msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" "s'ha actualitzat el repositori, però no s'ha pogut escriure\n" -" el fitxer «new_index». Comproveu que el disc no està ple i\n" -"que la quota no s'ha excedit, i després, feu\n" -"«git restore --staged :/» per a recuperar-lo." +"el fitxer d'Ãndex nou. Comproveu que el disc no està ple i\n" +"la quota no s'ha excedit, i després feu «git restore --staged :/n»\n" +"per a recuperar-ho." msgid "git config [<options>]" msgstr "git config [<opcions>]" @@ -5551,7 +5565,7 @@ msgstr "No s'ha trobat cap nom, no es pot descriure res." #, c-format msgid "option '%s' and commit-ishes cannot be used together" -msgstr "les opcions «%s» i de comissió no es poden usar juntes" +msgstr "opció «%s» i les de comissió no es poden usar juntes" msgid "" "git diagnose [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n" @@ -5716,7 +5730,7 @@ msgstr "selecciona la gestió de les etiquetes que etiquetin objectes filtrats" msgid "select handling of commit messages in an alternate encoding" msgstr "" -"selecciona la gestió dels missatges de publicació en una codificació " +"selecciona la gestió dels missatges de comissió en una codificació " "alternativa" msgid "dump marks to this file" @@ -6585,6 +6599,9 @@ msgstr "poda objectes sense referència" msgid "pack unreferenced objects separately" msgstr "empaqueta els objectes no referenciats de forma separada" +msgid "with --cruft, limit the size of new cruft packs" +msgstr "amb --cruft, limiteu la mida dels paquets cruft nous" + msgid "be more thorough (increased runtime)" msgstr "sigues més exhaustiu (el temps d'execució augmenta)" @@ -6763,12 +6780,6 @@ msgstr "" msgid "'crontab' died" msgstr "«crontab» ha mort" -msgid "failed to start systemctl" -msgstr "s'ha produït un error en iniciar systemctl" - -msgid "failed to run systemctl" -msgstr "s'ha produït un error en executar systemctl" - #, c-format msgid "failed to delete '%s'" msgstr "s'ha produït un error en suprimir «%s»" @@ -6777,6 +6788,12 @@ msgstr "s'ha produït un error en suprimir «%s»" msgid "failed to flush '%s'" msgstr "no s'ha pogut buidar «%s»" +msgid "failed to start systemctl" +msgstr "s'ha produït un error en iniciar systemctl" + +msgid "failed to run systemctl" +msgstr "s'ha produït un error en executar systemctl" + #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "l'argument --scheduler no reconegut «%s»" @@ -6800,6 +6817,9 @@ msgstr "planificador" msgid "scheduler to trigger git maintenance run" msgstr "planificador per a activar l'execució de manteniment del git" +msgid "failed to set up maintenance schedule" +msgstr "no s'ha pogut configurar la planificació del manteniment" + msgid "failed to add repo to global config" msgstr "no s'ha pogut afegir un repositori a la configuració global" @@ -6831,6 +6851,10 @@ msgid "unable to read tree (%s)" msgstr "no s'ha pogut llegir l'arbre (%s)" #, c-format +msgid "unable to read tree %s" +msgstr "no s'ha pogut llegir l'arbre %s" + +#, c-format msgid "unable to grep from object of type %s" msgstr "no es pot fer grep des d'un objecte de tipus %s" @@ -6874,8 +6898,8 @@ msgstr "processa els fitxers binaris amb filtres de textconv" msgid "search in subdirectories (default)" msgstr "cerca als subdirectoris (per defecte)" -msgid "descend at most <depth> levels" -msgstr "descendeix com a mà xim <profunditat> nivells" +msgid "descend at most <n> levels" +msgstr "descendeix com a mà xim <n> nivells" msgid "use extended POSIX regular expressions" msgstr "usa les expressions regulars POSIX ampliades" @@ -7249,10 +7273,6 @@ msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "S'HA TROBAT UNA COL·LISIÓ SHA1 AMB %s !" #, c-format -msgid "unable to read %s" -msgstr "no s'ha pogut llegir %s" - -#, c-format msgid "cannot read existing object info %s" msgstr "no es pot llegir la informació d'objecte existent %s" @@ -7392,11 +7412,13 @@ msgstr "error fsck als objectes del paquet" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" @@ -7441,12 +7463,12 @@ msgstr "--separate-git-dir és incompatible amb un repositori nu" msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" -" [--parse] [<fitxer>...]" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" +" [--parse] [<file>...]" msgid "edit files in place" msgstr "edita els fitxers in situ" @@ -7454,6 +7476,9 @@ msgstr "edita els fitxers in situ" msgid "trim empty trailers" msgstr "escurça els remolcs buits" +msgid "placement" +msgstr "posicionament" + msgid "where to place the new trailer" msgstr "on ubicar el «trailer» nou" @@ -7466,17 +7491,18 @@ msgstr "acció si el «trailer» falta" msgid "output only the trailers" msgstr "mostra només els «trailer»" -msgid "do not apply config rules" -msgstr "no apliquis les regles de configuració" +msgid "do not apply trailer.* configuration variables" +msgstr "no apliquis les variables de configuració trailer.*" -msgid "join whitespace-continued values" -msgstr "uneix els valors continus amb espais en blanc" +msgid "reformat multiline trailer values as single-line values" +msgstr "" +"reformata els valors del trà iler multilÃnia com a valors de lÃnia única" -msgid "set parsing options" -msgstr "estableix les opcions d'anà lisi" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "à lies per a --only-trailers --only-input --unfold" -msgid "do not treat --- specially" -msgstr "no tractis --- especialment" +msgid "do not treat \"---\" as the end of input" +msgstr "no tractis «---» com el final de l'entrada" msgid "trailer(s) to add" msgstr "remolcs a afegir" @@ -7565,6 +7591,10 @@ msgstr "necessita exactament un interval" msgid "not a range" msgstr "no és un interval" +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "no es pot llegir el fitxer de descripció de la branca «%s»" + msgid "cover letter needs email format" msgstr "la carta de presentació necessita un format de correu electrònic" @@ -7666,6 +7696,9 @@ msgstr "" "genera parts d'una carta de presentació basant-se en la descripció d'una " "branca" +msgid "use branch description from file" +msgstr "utilitza la descripció de la branca des del fitxer" + msgid "use [<prefix>] instead of [PATCH]" msgstr "useu [<prefix>] en comptes de [PATCH]" @@ -8101,9 +8134,18 @@ msgstr "" "git merge-file [<opcions>] [-L <nom1> [-L <original> [-L <nom2>]]] <fitxer1> " "<fitxer-original> <fitxer2>" +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"l'opció diff-algorithm accepta «myers», «minimal», «patience» i «histogram»" + msgid "send results to standard output" msgstr "envia els resultats a la sortida està ndard" +msgid "use object IDs instead of filenames" +msgstr "utilitza els ID dels objectes en comptes dels noms de fitxer" + msgid "use a diff3 based merge" msgstr "usa una fusió basada en diff3" @@ -8119,6 +8161,12 @@ msgstr "en conflictes, usa la seva versió" msgid "for conflicts, use a union version" msgstr "en conflictes, usa una versió d'unió" +msgid "<algorithm>" +msgstr "<algorisme>" + +msgid "choose a diff algorithm" +msgstr "trieu un algorisme per al diff" + msgid "for conflicts, use this marker size" msgstr "en conflictes, usa aquesta mida de marcador" @@ -8129,6 +8177,13 @@ msgid "set labels for file1/orig-file/file2" msgstr "estableix les etiquetes per a fitxer1/fitxer-original/fitxer2" #, c-format +msgid "object '%s' does not exist" +msgstr "l'objecte «%s» no existeix" + +msgid "Could not write object file" +msgstr "No s'ha pogut escriure el fitxer de l'objecte" + +#, c-format msgid "unknown option %s" msgstr "opció desconeguda %s" @@ -8189,11 +8244,18 @@ msgstr "realitza múltiples fusions, una per lÃnia d'entrada" msgid "specify a merge-base for the merge" msgstr "cal especificar una referència base per a la fusió" +msgid "option=value" +msgstr "opció=valor" + +msgid "option for selected merge strategy" +msgstr "opció per a l'estratègia de fusió seleccionada" + msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge és incompatible amb totes les altres opcions" -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base és incompatible amb --stdin" +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "opció d'estratègia desconeguda: -X%s" #, c-format msgid "malformed input line: '%s'." @@ -8263,12 +8325,6 @@ msgstr "estratègia" msgid "merge strategy to use" msgstr "estratègia de fusió a usar" -msgid "option=value" -msgstr "opció=valor" - -msgid "option for selected merge strategy" -msgstr "opció per a l'estratègia de fusió seleccionada" - msgid "merge commit message (for a non-fast-forward merge)" msgstr "missatge de comissió de fusió (per a una fusió no d'avanç rà pid)" @@ -8329,10 +8385,6 @@ msgid "Not handling anything other than two heads merge." msgstr "No s'està gestionant res a part de la fusió de dos caps." #, c-format -msgid "unknown strategy option: -X%s" -msgstr "opció d'estratègia desconeguda: -X%s" - -#, c-format msgid "unable to write %s" msgstr "no s'ha pogut escriure %s" @@ -8631,8 +8683,8 @@ msgstr "el destà existeix" msgid "can not move directory into itself" msgstr "no es pot moure un directori a dins d'ell mateix" -msgid "cannot move directory over file" -msgstr "no es pot moure un directori sobre un fitxer" +msgid "destination already exists" +msgstr "la destinació ja existeix" msgid "source directory is empty" msgstr "el directori d'origen està buit" @@ -9148,6 +9200,10 @@ msgid "inconsistency with delta count" msgstr "inconsistència amb el comptador de diferències" #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "valor pack.allowPackReuse value no và lid: «%s»" + +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -9394,9 +9450,6 @@ msgstr "el lÃmit mÃnim de mida del paquet és 1 MiB" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin no es pot utilitzar per a construir un paquet indexable" -msgid "cannot use --filter without --stdout" -msgstr "no es pot utilitzar --filter sense --stdout" - msgid "cannot use --filter with --stdin-packs" msgstr "no es pot utilitzar --filter sense --stdin-packs" @@ -9409,19 +9462,16 @@ msgstr "no es pot utilitzar la llista de revisió interna amb --cruft" msgid "cannot use --stdin-packs with --cruft" msgstr "no es pot --stdin-packs amb --cruft" -msgid "cannot use --max-pack-size with --cruft" -msgstr "no es pot usar --max-pack-size amb --cruft" - msgid "Enumerating objects" msgstr "S'estan enumerant els objectes" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "Total %<PRIu32> (%<PRIu32> diferències), reusats %<PRIu32> (%<PRIu32> " -"diferències), paquets reusats %<PRIu32>" +"diferències), paquets reusats %<PRIu32> (de %<PRIuMAX>)" msgid "" "'git pack-redundant' is nominated for removal.\n" @@ -10385,16 +10435,6 @@ msgstr "" msgid "switch `C' expects a numerical value" msgstr "«switch» «c» espera un valor numèric" -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy requereix --merge o --interactive" - -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "" -"les opcions «apply» són incompatibles amb rebase.autoSquash. Considereu " -"afegir-hi --no-autosquash" - msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -11106,6 +11146,10 @@ msgstr "" msgid "could not remove stale bitmap: %s" msgstr "no s'ha pogut eliminar el mapa de bits estancat: %s" +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "el prefix de paquet %s no comença amb objdir %s" + msgid "pack everything in a single pack" msgstr "empaqueta-ho tot en un únic paquet" @@ -11186,17 +11230,22 @@ msgid "pack prefix to store a pack containing pruned objects" msgstr "" "prefix del paquet per a emmagatzemar un paquet que contingui objectes podats" +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "" +"prefix del paquet per a emmagatzemar un paquet que contingui objectes " +"filtrats" + msgid "cannot delete packs in a precious-objects repo" msgstr "no es poden suprimir paquets en un repositori d'objectes preciosos" +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "l'opció «%s» només es pot utilitzar juntament amb «%s»" + msgid "Nothing new to pack." msgstr "Res nou a empaquetar." #, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "el prefix de paquet %s no comença amb objdir %s" - -#, c-format msgid "renaming pack to '%s' failed" msgstr "el canvi del nom a «%s» ha fallat" @@ -11397,6 +11446,77 @@ msgstr "--convert-graft-file arguments" msgid "only one pattern can be given with -l" msgstr "només es pot especificar un patró amb -l" +msgid "need some commits to replay" +msgstr "calen algunes comissions per tornar a reproduir" + +msgid "--onto and --advance are incompatible" +msgstr "--onto i --advance són incompatibles" + +msgid "all positive revisions given must be references" +msgstr "totes les revisions positives que s'han donat han de ser referències" + +msgid "argument to --advance must be a reference" +msgstr "l'argument per a --advance ha de ser una referència" + +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "" +"no es pot avançar l'objectiu amb múltiples fonts perquè l'ordenació no " +"estaria definida correctament" + +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "" +"no es pot determinar implÃcitament si aquesta és una operació --advance o --" +"onto" + +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "" +"no es pot avançar l'objectiu amb múltiples branques d'origen perquè " +"l'ordenació no estaria definida correctament" + +msgid "cannot implicitly determine correct base for --onto" +msgstr "no es pot determinar implÃcitament la base correcta per a --onto" + +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." + +msgid "make replay advance given branch" +msgstr "fes avançar la repetició de la branca donada" + +msgid "replay onto given commit" +msgstr "torna a reproduir a la comissió donada" + +msgid "advance all branches contained in revision-range" +msgstr "avança totes les branques contingudes a l'interval de revisions" + +msgid "option --onto or --advance is mandatory" +msgstr "l'opció --onto o --advance és obligatòria" + +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "" +"algunes opcions de referència se sobreescriuran de forma forçada com a «%s» " +"bits a «struct rev_info»" + +msgid "error preparing revisions" +msgstr "s'ha produït un error en preparar les revisions" + +msgid "replaying down to root commit is not supported yet!" +msgstr "encara no s'admet la reproducció cap avall en una comissió arrel" + +msgid "replaying merge commits is not supported yet!" +msgstr "encara no s'admet la repetició de les comissió de fusió" + msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" msgstr "" @@ -11605,18 +11725,12 @@ msgstr "--prefix requereix un argument" msgid "unknown mode for --abbrev-ref: %s" msgstr "mode desconegut per a --abbrev-ref: %s" -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden no es pot utilitzar juntament amb --branches" - -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden no es pot utilitzar juntament amb --tags" - -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden no es pot utilitzar juntament amb --remotes" - msgid "this operation must be run in a work tree" msgstr "aquesta operació s'ha d'executar en un arbre de treball" +msgid "Could not read the index" +msgstr "No s'ha pogut llegir l'Ãndex" + #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "mode desconegut per a --show-object-format: %s" @@ -11962,23 +12076,44 @@ msgid "Unknown hash algorithm" msgstr "Algorisme de resum desconegut" msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" -" [--heads] [--] [<patró>...]" +" [--heads] [--] [<pattern>...]" + +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<patró>]" +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <ref>" + +msgid "reference does not exist" +msgstr "la referència no existeix" + +msgid "failed to look up reference" +msgstr "s'ha produït en cercar la referència" + msgid "only show tags (can be combined with heads)" msgstr "mostra només les etiquetes (es pot combinar amb heads)" msgid "only show heads (can be combined with tags)" msgstr "mostra només els caps (es pot combinar amb tags)" +msgid "check for reference existence without resolving" +msgstr "comprova l'existència de referència sense resoldre" + msgid "stricter reference checking, requires exact ref path" msgstr "" "comprovació de referència més estricta, requereix el camà de referència " @@ -12808,6 +12943,9 @@ msgstr "" "shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] " "[--] [<camÃ>...]" +msgid "Failed to resolve HEAD as a valid ref." +msgstr "S'ha produït un error en resoldre HEAD com a referència và lida." + msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<opcions>] [<camÃ>...]" @@ -13282,6 +13420,9 @@ msgstr "(per a porcellanes) oblida't dels conflictes no resolts ni desats" msgid "write index in this format" msgstr "escriu l'Ãndex en aquest format" +msgid "report on-disk index format version" +msgstr "informa sobre la versió del format de l'Ãndex del disc" + msgid "enable or disable split index" msgstr "habilita o inhabilita l'Ãndex dividit" @@ -13306,6 +13447,14 @@ msgstr "marca els fitxers com a và lids pel fsmonitor" msgid "clear fsmonitor valid bit" msgstr "esborra el bit de validesa del fsmonitor" +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "index-version: era %d, s'ha establert a %d" + msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -13460,28 +13609,28 @@ msgstr "No hi ha cap branca d'origen possible, inferint «--orphan»" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan -b %s %s\n" msgstr "" -"Si voleu crear un arbre de treball que contingui una branca orfe nova\n" -"(branca sense comissions) per a aquest repositori, podeu fer-ho\n" +"Si voleu crear un arbre de treball que contingui una branca no nascuda\n" +"nova (branca sense comissions) per a aquest repositori, podeu fer-ho\n" "utilitzant l'argument --orphan:\n" "\n" " git worktree add --orphan -b %s %s\n" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan %s\n" msgstr "" -"Si voleu crear un arbre de treball que contingui una branca orfe nova\n" -"(branca sense comissions) per a aquest repositori, podeu fer-ho\n" +"Si voleu crear un arbre de treball que contingui una branca no nascuda\n" +"nova (branca sense comissions) per a aquest repositori, podeu fer-ho\n" "utilitzant l'argument --orphan:\n" "\n" " git worktree add --orphan %s\n" @@ -13544,6 +13693,10 @@ msgid "initializing" msgstr "s'està inicialitzant" #, c-format +msgid "could not find created worktree '%s'" +msgstr "no s'ha pogut trobar l'arbre de treball creat «%s»" + +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "S'està preparant l'arbre de treball (branca nova «%s»)" @@ -13577,14 +13730,10 @@ msgstr "" msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" -"No hi ha referències locals o remotes malgrat que hi existeix almenys un\n" -"remot, aturat; useu «add -f» per a forcar-ho o obtenir primer un remot" - -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "les opcions «%s» i «%s» no es poden usar juntes" +"No hi ha referències locals o remotes malgrat hi existeix almenys un\n" +"remot, aturada; useu «add -f» per a anul·lar o obtenir primer un remot" msgid "checkout <branch> even if already checked out in other worktree" msgstr "agafa <branca> encara que sigui agafada en altre arbre de treball" @@ -13595,8 +13744,8 @@ msgstr "crea una branca nova" msgid "create or reset a branch" msgstr "crea o restableix una branca" -msgid "create unborn/orphaned branch" -msgstr "crea una branca no nascuda/òrfena" +msgid "create unborn branch" +msgstr "crea una branca no nascuda" msgid "populate the new working tree" msgstr "emplena l'arbre de treball nou" @@ -13620,11 +13769,8 @@ msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "les opcions «%s», «%s», i «%s» no es poden usar juntes" #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "les opcions «%s» i «%s» no es poden usar juntes" - -msgid "<commit-ish>" -msgstr "<commit-ish>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "opció «%s» i les de comissió no es poden usar juntes" msgid "added with --lock" msgstr "afegit amb --lock" @@ -13901,6 +14047,10 @@ msgstr "" "l'identificador de fragment de finalització apareix abans del que s'esperava" #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "ID del fragment %<PRIx32> no alineat %d-byte" + +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "desplaçament incorrecte del fragment %<PRIx64> i %<PRIx64>" @@ -13954,10 +14104,8 @@ msgstr "Recopila la informació per a l'usuari per a enviar un informe d'error" msgid "Move objects and refs by archive" msgstr "Mou els objectes i les referències per arxiu" -msgid "Provide content or type and size information for repository objects" -msgstr "" -"Proveeix contingut o informació del tipus i mida per als objectes del " -"repositori" +msgid "Provide contents or details of repository objects" +msgstr "Proporcioneu el contingut o els detalls dels objectes del repositori" msgid "Display gitattributes information" msgstr "Mostra la informació de .gitattributes" @@ -14185,7 +14333,7 @@ msgid "Build a tree-object from ls-tree formatted text" msgstr "Construeix un objecte en arbre a partir de text formatat amb ls-tree" msgid "Write and verify multi-pack-indexes" -msgstr "Escriu i verifica els Ãndexs dels paquets multipaquet" +msgstr "Escriu i verifica els Ãndexs multipaquet" msgid "Move or rename a file, a directory, or a symlink" msgstr "Mou o canvia de nom a un fitxer, directori o enllaç simbòlic" @@ -14252,6 +14400,11 @@ msgstr "Empaqueta els objectes desempaquetats en un repositori" msgid "Create, list, delete refs to replace objects" msgstr "Crea, llista i esborra referències per a substituir objectes" +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "" +"EXPERIMENTAL: torna a reproduir comissions sobre una nova base, també " +"funciona amb repositoris nus" + msgid "Generates a summary of pending changes" msgstr "Genera un resum dels canvis pendents" @@ -14376,8 +14529,8 @@ msgstr "Verifica la signatura GPG de les etiquetes" msgid "Display version information about Git" msgstr "Mostra informació de la versió del Git" -msgid "Show logs with difference each commit introduces" -msgstr "Mostra registres amb la diferència introduïda per cada comissió" +msgid "Show logs with differences each commit introduces" +msgstr "Mostra els registres amb les diferències que introdueix cada comissió" msgid "Manage multiple working trees" msgstr "Gestiona múltiples arbres de treball" @@ -14493,6 +14646,35 @@ msgstr "Una eina per a gestionar dipòsits Git grans" msgid "commit-graph file is too small" msgstr "el fitxer del graf de comissions és massa petit" +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "" +"el fragment de «fanout» de l'oid del graf de comissions és de mida incorrecta" + +msgid "commit-graph fanout values out of order" +msgstr "valors de graf de comissions de «fanout» estan fora d'ordre" + +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "el fragment de cerca OID és de mida incorrecta" + +msgid "commit-graph commit data chunk is wrong size" +msgstr "el fragment de dades del graf de comissions és de mida incorrecta" + +msgid "commit-graph generations chunk is wrong size" +msgstr "" +"el fragment de les generacions del graf de comissions és de mida incorrecta" + +msgid "commit-graph changed-path index chunk is too small" +msgstr "" +"el fragment d'Ãndex del canvi del camà del graf de comissions és massa petit" + +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "" +"s'ignorarà un fragment massa petit de camà canviat (%<PRIuMAX> < %<PRIuMAX>) " +"al fitxer del graf de comissions" + #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "" @@ -14512,9 +14694,26 @@ msgid "commit-graph file is too small to hold %u chunks" msgstr "" "el fitxer del graf de comissions és massa petit per a guardar %u fragments" +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "" +"manca o està malmès el fragment del «fanout» OID requerit al graf de " +"comissions" + +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "" +"manca o està malmès el fragment de cerca d'OID requerit al graf de comissions" + +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "" +"manca o està corromput el fragment de dades de publicació requerit al graf " +"de comissions" + msgid "commit-graph has no base graphs chunk" msgstr "el fragment del graf de comissions no té grafs de base" +msgid "commit-graph base graphs chunk is too small" +msgstr "el fragment de grafs base de la grà fica de comissió és massa petit" + msgid "commit-graph chain does not match" msgstr "la cadena del graf de comissions no coincideix" @@ -14522,6 +14721,9 @@ msgstr "la cadena del graf de comissions no coincideix" msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "el nombre de comissions en el graf base és massa alt: %<PRIuMAX>" +msgid "commit-graph chain file too small" +msgstr "el fitxer de cadena del graf de comissions és massa petit" + #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" msgstr "" @@ -14544,6 +14746,14 @@ msgstr "" "el graf de comissions requereix dades de generació de desbordaments però no " "en té cap" +msgid "commit-graph overflow generation data is too small" +msgstr "" +"les dades de generació de desbordament del graf de comissions són massa " +"petites" + +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "punter de vores extra del graf de comissió està fora dels lÃmits" + msgid "Loading known commits in commit graph" msgstr "S'estan carregant comissions conegudes al graf de comissions" @@ -14685,20 +14895,6 @@ msgid "commit-graph parent list for commit %s terminates early" msgstr "la llista pare del graf de comissions per %s acaba aviat" #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" -"el graf de comissions té nombre de generació zero per a la comissió %s, però " -"té no zero en altres llocs" - -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" -"el graf de comissions té un nombre de generació diferent de zero per a " -"comissió %s però té zero en altres llocs" - -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "" "generació del graf de comissions per a la comissió %s és %<PRIuMAX> < " @@ -14710,6 +14906,14 @@ msgstr "" "la data d'enviament per a la comissió %s en el graf de comissions és " "%<PRIuMAX> != %<PRIuMAX>" +#, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "" +"El graf de comissió té tant generacions zero com no nul·les (p. ex., " +"comissions «%s» i «%s»)" + msgid "Verifying commits in commit graph" msgstr "S'estan verificant les comissions al graf de comissions" @@ -14737,6 +14941,12 @@ msgstr "" "«git config advice.graftFileDeprecated false»" #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "" +"la comissió %s existeix al graf de comissions però no a la base de dades " +"d'objectes" + +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "La comissió %s té una signatura GPG no fiable, suposadament de %s." @@ -14918,7 +15128,7 @@ msgid "Regular expression too big" msgstr "Expressió regular és massa gran" msgid "Unmatched ) or \\)" -msgstr ") o \\) no no emparellat" +msgstr ") o \\) no emparellat" msgid "No previous regular expression" msgstr "No hi ha expressió regular anterior" @@ -15176,10 +15386,6 @@ msgstr "la referència «%s» no assenyala a un blob" msgid "unable to resolve config blob '%s'" msgstr "no s'ha pogut resoldre el blob de configuració: «%s»" -#, c-format -msgid "failed to parse %s" -msgstr "s'ha produït un error en analitzar %s" - msgid "unable to parse command-line config" msgstr "no s'ha pogut analitzar la configuració de la lÃnia d'ordres" @@ -15657,9 +15863,6 @@ msgstr "s'ha produït un error en escriure arxiu" msgid "--merge-base does not work with ranges" msgstr "--merge-base no funciona amb intervals" -msgid "--merge-base only works with commits" -msgstr "--merge-base només funciona amb comissions" - msgid "unable to get HEAD" msgstr "no s'ha pogut obtenir HEAD" @@ -15724,6 +15927,10 @@ msgstr "" "Valor desconegut de la variable de configuració de «diff.submodule»: «%s»" #, c-format +msgid "unknown value for config '%s': %s" +msgstr "valor desconegut per al config «%s»': %s" + +#, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" @@ -15800,12 +16007,6 @@ msgstr "argument --color-moved incorrecte: %s" msgid "invalid mode '%s' in --color-moved-ws" msgstr "mode «%s» no và lid en --color-moved-ws" -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"l'opció diff-algorithm accepta «myers», «minimal», «patience» i «histogram»" - #, c-format msgid "invalid argument to %s" msgstr "argument no và lid a %s" @@ -15850,8 +16051,8 @@ msgstr "llegible per una mà quina --stat" msgid "output only the last line of --stat" msgstr "mostra només l'última lÃnia de --stat" -msgid "<param1,param2>..." -msgstr "<param1,param2>..." +msgid "<param1>,<param2>..." +msgstr "<param1>,<param2>..." msgid "" "output the distribution of relative amount of changes for each sub-directory" @@ -15862,8 +16063,8 @@ msgstr "" msgid "synonym for --dirstat=cumulative" msgstr "sinònim de --dirstat=cumulative" -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "sinònim de --dirstat=files,param1,param2..." +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "sinònim de --dirstat=files,<param1>,<param2>..." msgid "warn if changes introduce conflict markers or whitespace errors" msgstr "" @@ -16046,12 +16247,6 @@ msgstr "genera diff usant l'algorisme «patience diff»" msgid "generate diff using the \"histogram diff\" algorithm" msgstr "genera diff usant l'algorisme «histogram diff»" -msgid "<algorithm>" -msgstr "<algorisme>" - -msgid "choose a diff algorithm" -msgstr "trieu un algorisme per al diff" - msgid "<text>" msgstr "<text>" @@ -17102,12 +17297,12 @@ msgstr "" "solucions possibles:\n" "%s" -msgid "Failed to execute internal merge" -msgstr "S'ha produït un error en executar la fusió interna" +msgid "failed to execute internal merge" +msgstr "no s'ha pogut executar la fusió interna" #, c-format -msgid "Unable to add %s to database" -msgstr "No s'ha pogut afegir %s a la base de dades" +msgid "unable to add %s to database" +msgstr "no s'ha pogut afegir %s a la base de dades" #, c-format msgid "Auto-merging %s" @@ -17556,7 +17751,21 @@ msgid "failed to read the cache" msgstr "s'ha produït un error en llegir la memòria cau" msgid "multi-pack-index OID fanout is of the wrong size" -msgstr "l'OID de l'Ãndex multipaquet és d'una mida incorrecta" +msgstr "l'OID «fanout» de l'Ãndex multipaquet és d'una mida incorrecta" + +#, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"oid «fanout» desordenat: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" + +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "El fragment de cerca OID Ãndex multipaquet és de mida incorrecta" + +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "" +"el fragment de desplaçament de l'objecte Ãndex multipaquet és d'una mida " +"incorrecta" #, c-format msgid "multi-pack-index file %s is too small" @@ -17577,17 +17786,28 @@ msgid "multi-pack-index hash version %u does not match version %u" msgstr "" "la versió del resum Ãndex multipaquet %u no coincideix amb la versió %u" -msgid "multi-pack-index missing required pack-name chunk" -msgstr "falta un fragment de nom de paquet necessari al multi-index" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "" +"manca o està malmès el fragment del nom de paquet requerit de l'Ãndex " +"multipaquet" -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "falta un fragment «fanout» OID necessari al multi-pack-index" +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "" +"manca o està malmès el fragment del «fanout» OID requerit a l'Ãndex " +"multipaquet" -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "falta un fragment de cerca «fanout» OID necessari al multi-pack-index" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "" +"manca o està malmès el fragment de cerca d'OID necessari a l'Ãndex " +"multipaquet" -msgid "multi-pack-index missing required object offsets chunk" -msgstr "falta un fragment necessari dels desplaçaments al multi-pack-index" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "" +"manca o està malmès el fragment de l'Ãndex multipaquet dels objectes " +"requerits" + +msgid "multi-pack-index pack-name chunk is too short" +msgstr "el fragment de nom de l'Ãndex multipaquet és massa curt" #, c-format msgid "multi-pack-index pack names out of order: '%s' before '%s'" @@ -17599,11 +17819,21 @@ msgstr "" msgid "bad pack-int-id: %u (%u total packs)" msgstr "pack-int-id: %u incorrecte (%u paquets en total)" +msgid "MIDX does not contain the BTMP chunk" +msgstr "MIDX no conté el fragment BTMP" + +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "no s'ha pogut carregar el paquet amb bits %<PRIu32>" + msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "" "l'Ãndex multipaquet emmagatzema un desplaçament de 64 bits, però off_t és " "massa petit" +msgid "multi-pack-index large offset out of bounds" +msgstr "desplaçament gran de l'Ãndex multipaquet està fora dels lÃmits" + #, c-format msgid "failed to add packfile '%s'" msgstr "no s'ha pogut afegir el fitxer de paquet «%s»" @@ -17684,11 +17914,6 @@ msgstr "suma de verificació incorrecta" msgid "Looking for referenced packfiles" msgstr "S'estan cercant fitxers empaquetats referenciats" -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "oid fanout desordenat: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" - msgid "the midx contains no oid" msgstr "el midx no conté cap oid" @@ -18163,7 +18388,7 @@ msgid "hash mismatch %s" msgstr "el resum no coincideix %s" msgid "trying to write commit not in index" -msgstr "s'està intentant no escriure la publicació a l'Ãndex" +msgstr "s'està intentant no escriure la comissió a l'Ãndex" msgid "failed to load bitmap index (corrupted?)" msgstr "" @@ -18220,6 +18445,9 @@ msgstr "falta l'Ãndex invers necessari al mapa de bits multipaquet" msgid "could not open pack %s" msgstr "no s'ha pogut obrir el paquet %s" +msgid "could not determine MIDX preferred pack" +msgstr "no s'ha pogut determinar el paquet preferit MIDX" + #, c-format msgid "preferred pack (%s) is invalid" msgstr "el paquet preferit (%s) no és và lid" @@ -18246,6 +18474,12 @@ msgstr "" "comissió «%s»" #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "" +"no s'ha pogut carregar el paquet: «%s», s'està inhabilitant lareutilització " +"de paquets" + +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "no s'ha trobat l'objecte «%s» als tipus de mapes de bits" @@ -18334,6 +18568,13 @@ msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "" "posició no và lida de l'Ãndex de reversió a %<PRIu64>: %<PRIu32> != %<PRIu32>" +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "" +"el fragment de l'index invers de l'Ãndex multipaquet és de mida incorrecta" + +msgid "could not determine preferred pack" +msgstr "no s'ha pogut determinar el paquet preferit" + msgid "cannot both write and verify reverse index" msgstr "no es pot escriure i verificar l'Ãndex invers" @@ -18387,14 +18628,6 @@ msgid "%s requires a value" msgstr "%s requereix un valor" #, c-format -msgid "%s is incompatible with %s" -msgstr "%s és incompatible amb %s" - -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s: és incompatible amb alguna altra cosa" - -#, c-format msgid "%s takes no value" msgstr "%s no accepta cap valor" @@ -18477,6 +18710,10 @@ msgstr " %s" msgid "-NUM" msgstr "-NUM" +#, c-format +msgid "opposite of --no-%s" +msgstr "oposat a --no-%s" + msgid "expiry-date" msgstr "data-de-caducitat" @@ -18508,6 +18745,14 @@ msgstr "" "separats amb el carà cter NUL" #, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "el valor «%s» booleà de l'entorn és incorrecte per a «%s»" + +#, c-format +msgid "failed to parse %s" +msgstr "s'ha produït un error en analitzar %s" + +#, c-format msgid "Could not make %s writable by group" msgstr "No s'ha pogut fer %s escrivible pel grup" @@ -18558,6 +18803,10 @@ msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s: «literal» i «glob» són incompatibles" #, c-format +msgid "'%s' is outside the directory tree" +msgstr "«%s» és fora de l'arbre de directoris" + +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s: «%s» està fora del repositori en «%s»" @@ -18713,10 +18962,6 @@ msgid "unable to add '%s' to index" msgstr "no s'ha pogut afegir «%s» a l'Ãndex" #, c-format -msgid "unable to stat '%s'" -msgstr "no s'ha pogut fer «stat» a «%s»" - -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "«%s» apareix com a fitxer i com a directori" @@ -18824,10 +19069,6 @@ msgid "failed to convert to a sparse-index" msgstr "s'ha produït un error en convertir a un Ãndex dispers" #, c-format -msgid "could not stat '%s'" -msgstr "no s'ha pogut fer stat a «%s»" - -#, c-format msgid "unable to open git dir: %s" msgstr "no s'ha pogut obrir el directori git: %s" @@ -19302,10 +19543,6 @@ msgid "cannot process '%s' and '%s' at the same time" msgstr "no es poden processar «%s» i «%s» a la vegada" #, c-format -msgid "could not remove reference %s" -msgstr "no s'ha pogut eliminar la referència %s" - -#, c-format msgid "could not delete reference %s: %s" msgstr "no s'ha pogut suprimir la referència %s: %s" @@ -19529,7 +19766,7 @@ msgid "" "'%s:refs/tags/%s'?" msgstr "" "La part <src> de l'especificació de la referència és un objecte d'etiqueta.\n" -"Voleu crear una etiqueta pujant-la a «%srefs/tags/%s»?" +"Voleu crear una etiqueta pujant-la a «%s:refs/tags/%s»?" #, c-format msgid "" @@ -19538,7 +19775,7 @@ msgid "" "'%s:refs/tags/%s'?" msgstr "" "La part <src> de l'especificació de la referència és un objecte d'arbre.\n" -"Voleu crear una etiqueta pujant-la a «%srefs/tags/%s»?" +"Voleu crear una etiqueta pujant-la a «%s:refs/tags/%s»?" #, c-format msgid "" @@ -19870,8 +20107,15 @@ msgstr "quan es clona, crear un directori de treball complet" msgid "only download metadata for the branch that will be checked out" msgstr "només baixa les metadades per a la branca que s'agafarà " -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [<opcions>] [--] <repositori> [<dir>]" +msgid "create repository within 'src' directory" +msgstr "crea un repositori dins del directori «src»" + +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -19922,12 +20166,28 @@ msgid "could not remove stale scalar.repo '%s'" msgstr "no s'ha pogut suprimir el scalar.repo «%s» estancat" #, c-format -msgid "removing stale scalar.repo '%s'" -msgstr "s'està eliminant el scalar.repo «%s» estancat" +msgid "removed stale scalar.repo '%s'" +msgstr "s'ha eliminat l'scalar.repo estancat «%s»" #, c-format -msgid "git repository gone in '%s'" -msgstr "no existeix un repositori de git a: «%s»" +msgid "repository at '%s' has different owner" +msgstr "el dipòsit a «%s» té un propietari diferent" + +#, c-format +msgid "repository at '%s' has a format issue" +msgstr "el dipòsit a «%s» té un problema de format" + +#, c-format +msgid "repository not found in '%s'" +msgstr "no s'ha trobat el dipòsit a «%s»" + +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"per a desregistrar aquest dipòsit de l'escalar, executeu\n" +"\tgit config --global --unset --fixed-value scalar.repo «%s»" msgid "" "scalar run <task> [<enlistment>]\n" @@ -20335,10 +20595,6 @@ msgid "%s: cannot parse parent commit %s" msgstr "%s: no es pot analitzar la comissió pare %s" #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "no s'ha pogut canviar el nom «%s» a «%s»" - -#, c-format msgid "could not revert %s... %s" msgstr "no s'ha pogut revertir %s... %s" @@ -20663,6 +20919,9 @@ msgid "Autostash exists; creating a new stash entry." msgstr "" "El «stash» automà tic ja existeix; s'està creant una entrada «stash» nova." +msgid "autostash reference is a symref" +msgstr "la referència d'autostash és un symref" + msgid "could not detach HEAD" msgstr "no s'ha pogut separar HEAD" @@ -20695,14 +20954,14 @@ msgstr "" " git rebase --continue\n" #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "S'està fent «rebase» (%d/%d)%s" - -#, c-format msgid "Stopped at %s... %.*s\n" msgstr "Aturat a %s... %.*s\n" #, c-format +msgid "Rebasing (%d/%d)%s" +msgstr "S'està fent «rebase» (%d/%d)%s" + +#, c-format msgid "unknown command %d" msgstr "ordre %d desconeguda" @@ -20906,7 +21165,8 @@ 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 "" -"no és un repositori de git (ni cap pare fins al punt de muntatge %s)\n" +"no és un repositori de git (ni existeix cap pare fins al punt de muntatge " +"%s)\n" "S'atura a la frontera de sistema de fitxers (GIT_DISCOVERY_ACROSS_FILESYSTEM " "no està establert)." @@ -20979,6 +21239,10 @@ msgid "invalid initial branch name: '%s'" msgstr "nom de branca inicial no và lid: «%s»" #, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "reinicialització: s'ha ignorat --initial-branch=%s" + +#, c-format msgid "unable to handle file type %d" msgstr "no s'ha pogut gestionar el tipus de fitxer %d" @@ -20989,15 +21253,17 @@ msgstr "no s'ha pogut moure %s a %s" msgid "attempt to reinitialize repository with different hash" msgstr "s'ha intentat reinicialitzar el repositori amb un resum diferent" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "" +"s'ha intentat reactivar el repositori amb un format d'emmagatzematge de " +"referència diferent" + #, c-format msgid "%s already exists" msgstr "%s ja existeix" #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "reinicialització: s'ha ignorat --initial-branch=%s" - -#, c-format msgid "Reinitialized existing shared Git repository in %s%s\n" msgstr "S'ha reinicialitzat el repositori compartit existent del Git en %s%s\n" @@ -21266,12 +21532,6 @@ msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "" "nombre d'entrades a l'arbre de la memòria cau a invalidar (per defecte 0)" -msgid "unhandled options" -msgstr "opcions no gestionades" - -msgid "error preparing revisions" -msgstr "s'ha produït un error en preparar les revisions" - #, c-format msgid "commit %s is not marked reachable" msgstr "la comissió %s no està marcada com abastable" @@ -21424,9 +21684,6 @@ msgstr "el protocol no permet establir el camà del servei remot" msgid "invalid remote service path" msgstr "el camà del servei remot no és và lid" -msgid "operation not supported by protocol" -msgstr "opció no admesa pel protocol" - #, c-format msgid "can't connect to subservice %s" msgstr "no es pot connectar al subservei %s" @@ -21559,10 +21816,6 @@ msgstr "" "encara no s'ha implementat la compatibilitat amb la versió v2 del protocol" #, c-format -msgid "unknown value for config '%s': %s" -msgstr "valor desconegut per al config «%s»': %s" - -#, c-format msgid "transport '%s' not allowed" msgstr "no es permet el transport «%s»" @@ -21615,6 +21868,9 @@ msgid "could not retrieve server-advertised bundle-uri list" msgstr "" "no s'ha pogut recuperar la llista de paquets d'URI anunciats pel servidor" +msgid "operation not supported by protocol" +msgstr "opció no admesa pel protocol" + msgid "too-short tree object" msgstr "objecte d'arbre massa curt" @@ -22012,6 +22268,9 @@ msgstr "no s'ha pogut accedir a «%s»" msgid "unable to get current working directory" msgstr "no s'ha pogut obtenir el directori de treball actual" +msgid "unable to get random bytes" +msgstr "no s'han pogut obtenir bytes aleatoris" + msgid "Unmerged paths:" msgstr "Camins sense fusionar:" @@ -22453,6 +22712,10 @@ msgstr "addicionalment, el vostre Ãndex conté canvis sense cometre." msgid "cannot %s: Your index contains uncommitted changes." msgstr "no es pot %s: El vostre Ãndex conté canvis sense cometre." +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "estil desconegut «%s» donat per a «%s»" + msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" @@ -22639,13 +22902,13 @@ msgstr "" "Esborreu el contingut del cos si no voleu enviar cap resum.\n" #, perl-format -msgid "Failed to open %s: %s" -msgstr "S'ha produït un error en obrir %s: %s" - -#, perl-format msgid "Failed to open %s.final: %s" msgstr "S'ha produït un error en obrir %s.final: %s" +#, perl-format +msgid "Failed to open %s: %s" +msgstr "S'ha produït un error en obrir %s: %s" + msgid "Summary email is empty, skipping it\n" msgstr "El correu electrònic de resum està buit, s'omet\n" @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-17 16:53+0200\n" -"PO-Revision-Date: 2023-08-17 16:55+0200\n" +"POT-Creation-Date: 2024-02-17 18:07+0100\n" +"PO-Revision-Date: 2024-02-17 18:14+0100\n" "Last-Translator: Ralf Thielow <ralf.thielow@gmail.com>\n" "Language-Team: German\n" "Language: de\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" -"X-Generator: Poedit 3.3.2\n" +"X-Generator: Poedit 3.4.1\n" #, c-format msgid "Huh (%s)?" @@ -1474,6 +1474,10 @@ msgid "Unexpected option --output" msgstr "Unerwartete Option --output" #, c-format +msgid "extra command line parameter '%s'" +msgstr "zusätzlicher Befehlszeilenparameter '%s'" + +#, c-format msgid "Unknown archive format '%s'" msgstr "Unbekanntes Archivformat '%s'" @@ -1519,6 +1523,14 @@ msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "ungültiges --attr-source oder GIT_ATTR_SOURCE" #, c-format +msgid "unable to stat '%s'" +msgstr "konnte '%s' nicht lesen" + +#, c-format +msgid "unable to read %s" +msgstr "kann %s nicht lesen" + +#, c-format msgid "Badly quoted content in file '%s': %s" msgstr "Ungültiger Inhalt bzgl. Anführungszeichen in Datei '%s': %s" @@ -1807,8 +1819,8 @@ msgid "submodule '%s': cannot create branch '%s'" msgstr "Submodul '%s': kann Branch nicht erzeugen: '%s'" #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "'%s' ist bereits in '%s' ausgecheckt" +msgid "'%s' is already used by worktree at '%s'" +msgstr "'%s' wird bereits von Arbeitsverzeichnis in '%s' verwendet" msgid "git add [<options>] [--] <pathspec>..." msgstr "git add [<Optionen>] [--] <Pfadspezifikation>..." @@ -1828,25 +1840,22 @@ msgstr "" "Die Einstellung add.interactive.useBuiltin wurde entfernt!\n" "Siehe den Eintrag in 'git help config' für Details." -msgid "Could not read the index" -msgstr "Konnte den Index nicht lesen" - -msgid "Could not write patch" -msgstr "Konnte Patch nicht schreiben" +msgid "could not read the index" +msgstr "konnte den Index nicht lesen" msgid "editing patch failed" msgstr "Bearbeitung des Patches fehlgeschlagen" #, c-format -msgid "Could not stat '%s'" -msgstr "Konnte Verzeichnis '%s' nicht lesen" +msgid "could not stat '%s'" +msgstr "Konnte '%s' nicht lesen." -msgid "Empty patch. Aborted." -msgstr "Leerer Patch. Abgebrochen." +msgid "empty patch. aborted" +msgstr "leerer Patch. Abgebrochen" #, c-format -msgid "Could not apply '%s'" -msgstr "Konnte '%s' nicht anwenden." +msgid "could not apply '%s'" +msgstr "konnte '%s' nicht anwenden" msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" @@ -1985,6 +1994,9 @@ msgstr "" msgid "index file corrupt" msgstr "Index-Datei beschädigt" +msgid "unable to write new index file" +msgstr "Konnte neue Index-Datei nicht schreiben." + #, c-format msgid "bad action '%s' for '%s'" msgstr "ungültige Aktion '%s' für '%s'" @@ -2199,9 +2211,6 @@ msgstr "" "Sie können `git rm` auf Dateien ausführen, um \"von denen gelöscht\" für\n" "diese zu akzeptieren." -msgid "unable to write new index file" -msgstr "Konnte neue Index-Datei nicht schreiben." - #, c-format msgid "Could not parse object '%s'." msgstr "Konnte Objekt '%s' nicht parsen." @@ -2220,11 +2229,6 @@ msgstr "" msgid "failed to read '%s'" msgstr "Fehler beim Lesen von '%s'" -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "" -"die Optionen '%s=%s' und '%s=%s' können nicht gemeinsam verwendet werden" - msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<Optionen>] [(<mbox> | <E-Mail-Verzeichnis>)...]" @@ -2376,11 +2380,11 @@ msgid "git archive: expected a flush" msgstr "git archive: erwartete eine Spülung (flush)" msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=<Begriff> --term-{old,good}=<Begriff>] [--" -"no-checkout] [--first-parent] [<schlecht> [<gut>...]] [--] " +"git bisect start [--term-(new|bad)=<Begriff> --term-(old|good)=<Begriff>] " +"[--no-checkout] [--first-parent] [<schlecht> [<gut>...]] [--] " "[<Pfadspezifikation>...]" msgid "git bisect (good|bad) [<rev>...]" @@ -2395,8 +2399,8 @@ msgstr "git bisect reset [<Commit>]" msgid "git bisect replay <logfile>" msgstr "git bisect replay <Logdatei>" -msgid "git bisect run <cmd>..." -msgstr "git bisect run <Programm>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <Programm> [<Argument>...]" #, c-format msgid "cannot open file '%s' in mode '%s'" @@ -2818,44 +2822,46 @@ msgstr "git branch [<Optionen>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" -"entferne Branch '%s', der zusammengeführt wurde mit\n" -" '%s', aber noch nicht mit HEAD zusammengeführt wurde." +"Löschen des Branches '%s', der mit\n" +" '%s', aber noch nicht in HEAD zusammengeführt wurde" #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" "entferne Branch '%s' nicht, der noch nicht zusammengeführt wurde mit\n" -" '%s', obwohl er mit HEAD zusammengeführt wurde." +" '%s', obwohl er mit HEAD zusammengeführt wurde" #, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "Konnte Commit-Objekt für '%s' nicht nachschlagen." +msgid "couldn't look up commit object for '%s'" +msgstr "konnte Commit-Objekt für '%s' nicht nachschlagen" #, 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'." +msgid "the branch '%s' is not fully merged" +msgstr "der Branch '%s' ist nicht vollständig zusammengeführt" + +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" msgstr "" -"Der Branch '%s' ist nicht vollständig zusammengeführt.\n" -"Wenn Sie sicher sind diesen Branch zu entfernen, führen Sie 'git branch -D " -"%s' aus." +"Wenn Sie sicher sind, dass Sie den Branch löschen wollen, führen Sie 'git " +"branch -D %s' aus." -msgid "Update of config-file failed" +msgid "update of config-file failed" msgstr "Aktualisierung der Konfigurationsdatei fehlgeschlagen." msgid "cannot use -a with -d" msgstr "kann -a nicht mit -d benutzen" #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "Kann Branch '%s' nicht entfernen, ausgecheckt in '%s'." +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "" +"kann Branch '%s' nicht löschen, der in Arbeitsverzeichnis '%s' verwendet wird" #, c-format -msgid "remote-tracking branch '%s' not found." +msgid "remote-tracking branch '%s' not found" msgstr "Remote-Tracking-Branch '%s' nicht gefunden" #, c-format @@ -2867,8 +2873,8 @@ msgstr "" "Haben Sie --remote vergessen?" #, c-format -msgid "branch '%s' not found." -msgstr "Branch '%s' nicht gefunden." +msgid "branch '%s' not found" +msgstr "Branch '%s' nicht gefunden" #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" @@ -2889,56 +2895,56 @@ msgid "HEAD (%s) points outside of refs/heads/" msgstr "HEAD (%s) wurde nicht unter \"refs/heads/\" gefunden!" #, c-format -msgid "Branch %s is being rebased at %s" -msgstr "Branch %s wird auf %s umgesetzt" +msgid "branch %s is being rebased at %s" +msgstr "Rebase von Branch %s in %s im Gange" #, c-format -msgid "Branch %s is being bisected at %s" -msgstr "Binäre Suche von Branch %s zu %s im Gange" +msgid "branch %s is being bisected at %s" +msgstr "Binäre Suche von Branch %s in %s im Gange" #, c-format msgid "HEAD of working tree %s is not updated" msgstr "HEAD des Arbeitsverzeichnisses %s ist nicht aktualisiert" #, c-format -msgid "Invalid branch name: '%s'" +msgid "invalid branch name: '%s'" msgstr "Ungültiger Branchname: '%s'" #, c-format -msgid "No commit on branch '%s' yet." -msgstr "Noch kein Commit in Branch '%s'." +msgid "no commit on branch '%s' yet" +msgstr "Noch kein Commit in Branch '%s'" #, c-format -msgid "No branch named '%s'." -msgstr "Branch '%s' nicht vorhanden." +msgid "no branch named '%s'" +msgstr "kein Branch mit dem Namen '%s'" -msgid "Branch rename failed" +msgid "branch rename failed" msgstr "Umbenennung des Branches fehlgeschlagen" -msgid "Branch copy failed" +msgid "branch copy failed" msgstr "Kopie des Branches fehlgeschlagen" #, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "Kopie eines falsch benannten Branches '%s' erstellt." +msgid "created a copy of a misnamed branch '%s'" +msgstr "Kopie eines falsch benannten Branches '%s' erstellt" #, c-format -msgid "Renamed a misnamed branch '%s' away" +msgid "renamed a misnamed branch '%s' away" msgstr "falsch benannten Branch '%s' umbenannt" #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "Branch umbenannt zu %s, aber HEAD ist nicht aktualisiert!" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "Branch wird in %s umbenannt, aber HEAD wird nicht aktualisiert" -msgid "Branch is renamed, but update of config-file failed" +msgid "branch is renamed, but update of config-file failed" msgstr "" -"Branch ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist " -"fehlgeschlagen." +"Branch wurde umbenannt, aber die Aktualisierung der Konfigurationsdatei\n" +"ist fehlgeschlagen" -msgid "Branch is copied, but update of config-file failed" +msgid "branch is copied, but update of config-file failed" msgstr "" -"Branch wurde kopiert, aber die Aktualisierung der Konfigurationsdatei ist\n" -"fehlgeschlagen." +"Branch wurde kopiert, aber die Aktualisierung der Konfigurationsdatei\n" +"ist fehlgeschlagen" #, c-format msgid "" @@ -3053,8 +3059,8 @@ msgstr "Rekursion in Submodulen durchführen" msgid "format to use for the output" msgstr "für die Ausgabe zu verwendendes Format" -msgid "Failed to resolve HEAD as a valid ref." -msgstr "Konnte HEAD nicht als gültige Referenz auflösen." +msgid "failed to resolve HEAD as a valid ref" +msgstr "HEAD konnte nicht als gültige Referenz aufgelöst werden" msgid "HEAD not found below refs/heads!" msgstr "HEAD wurde nicht unter \"refs/heads\" gefunden!" @@ -3072,18 +3078,18 @@ msgstr "--recurse-submodules kann nur genutzt werden, um Branches zu erstellen" msgid "branch name required" msgstr "Branchname erforderlich" -msgid "Cannot give description to detached HEAD" +msgid "cannot give description to detached HEAD" msgstr "zu losgelöstem HEAD kann keine Beschreibung hinterlegt werden" msgid "cannot edit description of more than one branch" msgstr "Beschreibung von mehr als einem Branch kann nicht bearbeitet werden" -msgid "cannot copy the current branch while not on any." +msgid "cannot copy the current branch while not on any" msgstr "" "Kann den aktuellen Branch nicht kopieren, solange Sie sich auf keinem " "befinden." -msgid "cannot rename the current branch while not on any." +msgid "cannot rename the current branch while not on any" msgstr "" "Kann aktuellen Branch nicht umbenennen, solange Sie sich auf keinem befinden." @@ -3098,10 +3104,10 @@ msgstr "zu viele Argumente angegeben, um Upstream-Branch zu setzen" #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." +"could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" -"Konnte keinen neuen Upstream-Branch von HEAD zu %s setzen, da dieser auf\n" -"keinen Branch zeigt." +"konnte den Upstream von HEAD nicht auf %s setzen, wenn er auf keinen Zweig " +"verweist" #, c-format msgid "no such branch '%s'" @@ -3116,17 +3122,17 @@ msgstr "" "zu viele Argumente angegeben, um Konfiguration zu Upstream-Branch zu " "entfernen" -msgid "could not unset upstream of HEAD when it does not point to any branch." +msgid "could not unset upstream of HEAD when it does not point to any branch" msgstr "" -"Konnte Konfiguration zu Upstream-Branch von HEAD nicht entfernen, da dieser\n" -"auf keinen Branch zeigt." +"konnte den Upstream von HEAD nicht aufheben, wenn er nicht auf einen Zweig " +"verweist" #, c-format -msgid "Branch '%s' has no upstream information" -msgstr "Branch '%s' hat keinen Upstream-Branch gesetzt" +msgid "branch '%s' has no upstream information" +msgstr "Branch '%s' hat keine Upstream-Informationen" msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"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 "" "Die Optionen -a und -r bei 'git branch' können nicht mit einem Branchnamen " @@ -3135,7 +3141,7 @@ msgstr "" msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." +"'--set-upstream-to' instead" msgstr "" "Die '--set-upstream' Option wird nicht länger unterstützt.\n" "Bitte benutzen Sie stattdessen '--track' oder '--set-upstream-to'." @@ -3215,6 +3221,10 @@ msgid "specify a strftime format suffix for the filename(s)" msgstr "ein Suffix im strftime-Format für den/die Dateinamen angeben" #, c-format +msgid "unknown argument `%s'" +msgstr "unbekanntes Argument `%s'" + +#, c-format msgid "could not create leading directories for '%s'" msgstr "konnte vorangehende Verzeichnisse für '%s' nicht erstellen" @@ -3321,6 +3331,14 @@ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" msgstr "git cat-file (-t | -s) [--allow-unknown-type] <Objekt>" msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<Commit>:<Pfad|Commit-Referenz> | --path=<Pfad|Commit-" +"Referenz> <Commit>]" + +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -3331,14 +3349,6 @@ msgstr "" " [--buffer] [--follow-symlinks] [--unordered]\n" " [--textconv | --filters] [-Z]" -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<Commit>:<Pfad|Commit-Referenz> | --path=<Pfad|Commit-" -"Referenz> <Commit>]" - msgid "Check object existence or emit object contents" msgstr "Überprüfen von Objektexistenz oder Ausgeben von Objekt-Inhalten" @@ -3641,6 +3651,12 @@ msgid "'%s' or '%s' cannot be used with %s" msgstr "'%s' oder '%s' kann nicht mit %s verwendet werden" #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "" +"'%s', '%s' oder '%s' können beim Auschecken aus einem Verzeichnis nicht " +"verwendet werden" + +#, c-format msgid "path '%s' is unmerged" msgstr "Pfad '%s' ist nicht zusammengeführt" @@ -3900,8 +3916,8 @@ msgstr "Auschecken erzwingen (verwirft lokale Änderungen)" msgid "new-branch" msgstr "neuer Branch" -msgid "new unparented branch" -msgstr "neuer Branch ohne Eltern-Commit" +msgid "new unborn branch" +msgstr "neuer ungeborener Branch" msgid "update ignored files (default)" msgstr "ignorierte Dateien aktualisieren (Standard)" @@ -4155,9 +4171,6 @@ msgstr "" "clean.requireForce standardmäßig auf \"true\" gesetzt und weder -i, -n noch -" "f gegeben; \"clean\" verweigert" -msgid "-x and -X cannot be used together" -msgstr "-x und -X können nicht gemeinsam verwendet werden" - msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<Optionen>] [--] <Repository> [<Verzeichnis>]" @@ -4251,6 +4264,9 @@ msgstr ".git-Verzeichnis" msgid "separate git dir from working tree" msgstr "Git-Verzeichnis vom Arbeitsverzeichnis separieren" +msgid "specify the reference format to use" +msgstr "das zu verwendende Referenzformat angeben" + msgid "key=value" msgstr "Schlüssel=Wert" @@ -4374,12 +4390,9 @@ msgstr "Zu viele Argumente." msgid "You must specify a repository to clone." msgstr "Sie müssen ein Repository zum Klonen angeben." -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "" -"--bundle-uri ist inkompatibel mit --depth, --shallow-since und --shallow-" -"exclude" +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "unbekanntes Speicherformat für Referenzen '%s'" #, c-format msgid "repository '%s' does not exist" @@ -4521,7 +4534,7 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <Verzeichnis>] [--append]\n" " [--split[=<Strategie>]] [--reachable | --stdin-packs " @@ -4545,6 +4558,10 @@ msgid "Could not open commit-graph '%s'" msgstr "Konnte Commit-Graph '%s' nicht öffnen." #, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "konnte die Commit-Graph-Kette '%s' nicht öffnen" + +#, c-format msgid "unrecognized --split argument, %s" msgstr "nicht erkanntes --split Argument, %s" @@ -4747,9 +4764,6 @@ msgstr "Konnte temporären Index nicht aktualisieren." msgid "Failed to update main cache tree" msgstr "Konnte Haupt-Cache-Verzeichnis nicht aktualisieren" -msgid "unable to write new_index file" -msgstr "Konnte new_index Datei nicht schreiben" - msgid "cannot do a partial commit during a merge." msgstr "Kann keinen Teil-Commit durchführen, während ein Merge im Gange ist." @@ -5159,13 +5173,13 @@ msgstr "Commit aufgrund leerer Commit-Beschreibung abgebrochen.\n" msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" -"Das Repository wurde aktualisiert, aber die \"new_index\"-Datei\n" +"Das Repository wurde aktualisiert, aber die neue Index-Datei\n" "konnte nicht geschrieben werden. Prüfen Sie, dass Ihre Festplatte nicht\n" "voll und Ihr Kontingent nicht aufgebraucht ist und führen Sie\n" -"anschließend \"git restore HEAD --staged :/\" zur Wiederherstellung aus." +"anschließend \"git restore --staged :/\" zur Wiederherstellung aus." msgid "git config [<options>]" msgstr "git config [<Optionen>]" @@ -6643,6 +6657,9 @@ msgstr "unreferenzierte Objekte entfernen" msgid "pack unreferenced objects separately" msgstr "unreferenzierte Objekte separat verpacken" +msgid "with --cruft, limit the size of new cruft packs" +msgstr "mit --cruft, die Größe neuer Cruft-Pakete begrenzen" + msgid "be more thorough (increased runtime)" msgstr "mehr Gründlichkeit (erhöht Laufzeit)" @@ -6826,12 +6843,6 @@ msgstr "" msgid "'crontab' died" msgstr "'crontab' abgebrochen" -msgid "failed to start systemctl" -msgstr "Fehler beim Starten von systemctl" - -msgid "failed to run systemctl" -msgstr "Fehler beim Ausführen von systemctl" - #, c-format msgid "failed to delete '%s'" msgstr "Fehler beim Löschen von '%s'" @@ -6840,6 +6851,12 @@ msgstr "Fehler beim Löschen von '%s'" msgid "failed to flush '%s'" msgstr "Flush bei '%s' fehlgeschlagen." +msgid "failed to start systemctl" +msgstr "Fehler beim Starten von systemctl" + +msgid "failed to run systemctl" +msgstr "Fehler beim Ausführen von systemctl" + #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "nicht erkanntes --scheduler Argument '%s'" @@ -6863,6 +6880,9 @@ msgstr "Scheduler" msgid "scheduler to trigger git maintenance run" msgstr "Scheduler, um \"git maintenance run\" auzuführen" +msgid "failed to set up maintenance schedule" +msgstr "Fehler beim Einrichten des Wartungsplans" + msgid "failed to add repo to global config" msgstr "Repository konnte nicht zur globalen Konfiguration hinzugefügt werden" @@ -6893,6 +6913,10 @@ msgid "unable to read tree (%s)" msgstr "konnte \"Tree\"-Objekt (%s) nicht lesen" #, c-format +msgid "unable to read tree %s" +msgstr "konnte \"Tree\"-Objekt (%s) nicht lesen" + +#, c-format msgid "unable to grep from object of type %s" msgstr "kann \"grep\" nicht mit Objekten des Typs %s durchführen" @@ -6936,8 +6960,8 @@ msgstr "binäre Dateien mit \"textconv\"-Filtern verarbeiten" msgid "search in subdirectories (default)" msgstr "in Unterverzeichnissen suchen (Standard)" -msgid "descend at most <depth> levels" -msgstr "höchstens <Tiefe> Ebenen durchlaufen" +msgid "descend at most <n> levels" +msgstr "höchstens <n> Ebenen absteigen" msgid "use extended POSIX regular expressions" msgstr "erweiterte reguläre Ausdrücke aus POSIX verwenden" @@ -7314,10 +7338,6 @@ msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "SHA1 KOLLISION MIT %s GEFUNDEN !" #, c-format -msgid "unable to read %s" -msgstr "kann %s nicht lesen" - -#, c-format msgid "cannot read existing object info %s" msgstr "Kann existierende Informationen zu Objekt %s nicht lesen." @@ -7457,11 +7477,13 @@ msgstr "fsck Fehler beim Packen von Objekten" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" "git init [-q | --quiet] [--bare] [--template=<Vorlagenverzeichnis>]\n" " [--separate-git-dir <Git-Verzeichnis>] [--object-format=<Format>]\n" +" [--ref-format=<Format>]\n" " [-b <Branchname> | --initial-branch=<Branchname>]\n" " [--shared[=<Berechtigungen>]] [<Verzeichnis>]" @@ -7505,11 +7527,12 @@ msgstr "--separate-git-dir nicht kompatibel mit Bare-Repository" msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <Token>[(=|:)<Wert>])...]\n" +" [(--trailer (<Schlüssel>|<Schlüssel-Alias>)" +"[(=|:)<Wert>])...]\n" " [--parse] [<Datei>...]" msgid "edit files in place" @@ -7518,6 +7541,9 @@ msgstr "vorhandene Dateien direkt bearbeiten" msgid "trim empty trailers" msgstr "kürzt leere Anhänge" +msgid "placement" +msgstr "Platzierung" + msgid "where to place the new trailer" msgstr "wo der neue Anhang platziert wird" @@ -7530,17 +7556,17 @@ msgstr "Aktion, wenn Anhang fehlt" msgid "output only the trailers" msgstr "nur Anhänge ausgeben" -msgid "do not apply config rules" -msgstr "Regeln aus Konfiguration nicht anwenden" +msgid "do not apply trailer.* configuration variables" +msgstr "trailer.* Konfigurationsvariablen nicht anwenden" -msgid "join whitespace-continued values" -msgstr "durch Leerzeichen fortgesetzte Werte verbinden" +msgid "reformat multiline trailer values as single-line values" +msgstr "mehrzeilige Trailer als einzeilige Werte umformatieren" -msgid "set parsing options" -msgstr "Optionen für das Parsen setzen" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "Alias für --only-trailers --only-input --unfold" -msgid "do not treat --- specially" -msgstr "--- nicht speziell behandeln" +msgid "do not treat \"---\" as the end of input" +msgstr "\"---\" nicht als Ende der Eingabe behandeln" msgid "trailer(s) to add" msgstr "Anhang/Anhänge hinzufügen" @@ -7630,6 +7656,10 @@ msgstr "Brauche genau einen Commit-Bereich." msgid "not a range" msgstr "Kein Commit-Bereich." +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "konnte Datei mit Branchbeschreibung '%s' nicht lesen" + msgid "cover letter needs email format" msgstr "Anschreiben benötigt E-Mail-Format" @@ -7729,6 +7759,9 @@ msgid "generate parts of a cover letter based on a branch's description" msgstr "" "Erzeuge Teile des Deckblattes basierend auf der Beschreibung des Branches" +msgid "use branch description from file" +msgstr "Branchbeschreibung aus Datei verwenden" + msgid "use [<prefix>] instead of [PATCH]" msgstr "nutze [<Präfix>] statt [PATCH]" @@ -8171,9 +8204,19 @@ msgstr "" "git merge-file [<Optionen>] [-L <Name1> [-L <orig> [-L <Name2>]]] <Datei1> " "<orig-Datei> <Datei2>" +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"Option diff-algorithm akzeptiert: \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" + msgid "send results to standard output" msgstr "Ergebnisse zur Standard-Ausgabe senden" +msgid "use object IDs instead of filenames" +msgstr "Objekt-IDs anstelle von Dateinamen verwenden" + msgid "use a diff3 based merge" msgstr "einen diff3 basierten Merge verwenden" @@ -8189,6 +8232,12 @@ msgstr "bei Konflikten ihre Variante verwenden" msgid "for conflicts, use a union version" msgstr "bei Konflikten eine gemeinsame Variante verwenden" +msgid "<algorithm>" +msgstr "<Algorithmus>" + +msgid "choose a diff algorithm" +msgstr "einen Algorithmus für Änderungen wählen" + msgid "for conflicts, use this marker size" msgstr "bei Konflikten diese Kennzeichnungslänge verwenden" @@ -8199,6 +8248,13 @@ msgid "set labels for file1/orig-file/file2" msgstr "Beschriftung für Datei1/orig-Datei/Datei2 setzen" #, c-format +msgid "object '%s' does not exist" +msgstr "Objekt '%s' existiert nicht" + +msgid "Could not write object file" +msgstr "konnte Objektdatei nicht schreiben" + +#, c-format msgid "unknown option %s" msgstr "unbekannte Option: %s" @@ -8260,11 +8316,18 @@ msgstr "mehrere Merges durchführen, eine pro Eingabezeile" msgid "specify a merge-base for the merge" msgstr "Merge-Basis für den Merge angeben" +msgid "option=value" +msgstr "Option=Wert" + +msgid "option for selected merge strategy" +msgstr "Option für ausgewählte Merge-Strategie" + msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge ist mit allen anderen Optionen inkompatibel" -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base ist inkompatibel mit --stdin" +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "unbekannte Strategie-Option: -X%s" #, c-format msgid "malformed input line: '%s'." @@ -8335,12 +8398,6 @@ msgstr "Strategie" msgid "merge strategy to use" msgstr "zu verwendende Merge-Strategie" -msgid "option=value" -msgstr "Option=Wert" - -msgid "option for selected merge strategy" -msgstr "Option für ausgewählte Merge-Strategie" - msgid "merge commit message (for a non-fast-forward merge)" msgstr "" "Commit-Beschreibung zusammenführen (für einen Merge, der kein Vorspulen war)" @@ -8402,10 +8459,6 @@ msgid "Not handling anything other than two heads merge." msgstr "Es wird nur der Merge von zwei Branches behandelt." #, c-format -msgid "unknown strategy option: -X%s" -msgstr "unbekannte Strategie-Option: -X%s" - -#, c-format msgid "unable to write %s" msgstr "konnte %s nicht schreiben" @@ -8710,8 +8763,8 @@ msgstr "Ziel existiert bereits" msgid "can not move directory into itself" msgstr "kann Verzeichnis nicht in sich selbst verschieben" -msgid "cannot move directory over file" -msgstr "kann Verzeichnis nicht über Datei verschieben" +msgid "destination already exists" +msgstr "Ziel existiert bereits" msgid "source directory is empty" msgstr "Quellverzeichnis ist leer" @@ -9231,6 +9284,10 @@ msgid "inconsistency with delta count" msgstr "Inkonsistenz mit der Anzahl von Deltas" #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "ungültiger Wert für pack.allowPackReuse: '%s'" + +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -9480,9 +9537,6 @@ msgid "--thin cannot be used to build an indexable pack" msgstr "" "--thin kann nicht benutzt werden, um ein indizierbares Paket zu erstellen." -msgid "cannot use --filter without --stdout" -msgstr "Kann --filter nicht ohne --stdout benutzen." - msgid "cannot use --filter with --stdin-packs" msgstr "kann --filter nicht mit --stdin-packs benutzen" @@ -9496,19 +9550,16 @@ msgstr "interne Commit-Liste kann nicht gemeinsam mit --cruft verwendet werden" msgid "cannot use --stdin-packs with --cruft" msgstr "kann --stdin-packs nicht mit --cruft benutzen" -msgid "cannot use --max-pack-size with --cruft" -msgstr "kann --max-pack-size nicht mit --cruft benutzen" - msgid "Enumerating objects" msgstr "Objekte aufzählen" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "Gesamt %<PRIu32> (Delta %<PRIu32>), Wiederverwendet %<PRIu32> (Delta " -"%<PRIu32>), Pack wiederverwendet %<PRIu32>" +"%<PRIu32>), Paket wiederverwendet %<PRIu32> (von %<PRIuMAX>)" msgid "" "'git pack-redundant' is nominated for removal.\n" @@ -9893,9 +9944,9 @@ msgstr "" "Branches hinter seinem externen Gegenstück zurückgefallen ist. Wenn Sie\n" "die externen Änderungen integrieren wollen, verwenden Sie 'git pull' bevor\n" "Sie erneut push ausführen.\n" -"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help' für " -"weitere\n" -"Informationen." +"Siehe auch den Abschnitt 'Note about fast-forwards' in 'git push --help' " +"für\n" +"weitere Informationen." msgid "" "Updates were rejected because a pushed branch tip is behind its remote\n" @@ -9907,9 +9958,9 @@ msgstr "" "Branches hinter seinem externen Gegenstück zurückgefallen ist. Wenn Sie die\n" "externen Änderungen integrieren wollen, verwenden Sie 'git pull'\n" "bevor Sie erneut push ausführen.\n" -"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help' für " -"weitere\n" -"Informationen." +"Siehe auch den Abschnitt 'Note about fast-forwards' in 'git push --help' " +"für\n" +"weitere Informationen." msgid "" "Updates were rejected because the remote contains work that you do not\n" @@ -9926,9 +9977,9 @@ msgstr "" "Wenn Sie die externen Änderungen integrieren wollen, verwenden Sie 'git " "pull'\n" "bevor Sie erneut push ausführen.\n" -"Siehe auch die Sektion 'Note about fast-forwards' in 'git push --help' für " -"weitere\n" -"Informationen." +"Siehe auch den Abschnitt 'Note about fast-forwards' in 'git push --help' " +"für\n" +"weitere Informationen." msgid "Updates were rejected because the tag already exists in the remote." msgstr "" @@ -10519,16 +10570,6 @@ msgstr "" msgid "switch `C' expects a numerical value" msgstr "Schalter `C' erwartet einen numerischen Wert." -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy erfordert --merge oder --interactive" - -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "" -"apply-Optionen sind mit rebase.autoSquash nicht kompatibel. Erwägen Sie das " -"Hinzufügen von --no-autosquash" - msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -11246,6 +11287,10 @@ msgstr "konnte temporäre Referenzen-Snapshot-Datei nicht schließen" msgid "could not remove stale bitmap: %s" msgstr "konnte veraltete Bitmap nicht entfernen: %s" +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "Pack-Präfix %s fängt nicht mit objdir %s an" + msgid "pack everything in a single pack" msgstr "alles in eine einzige Pack-Datei packen" @@ -11324,17 +11369,20 @@ msgstr "ein Multi-Pack-Index des resultierenden Pakets schreiben" msgid "pack prefix to store a pack containing pruned objects" msgstr "pack-Präfix zum Speichern eines Pakets mit gelöschten Objekten" +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "Paketpräfix, um ein Paket mit herausgefilterten Objekten zu speichern" + msgid "cannot delete packs in a precious-objects repo" msgstr "kann Pack-Dateien in precious-objects Repository nicht löschen" +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "Option '%s' kann nur zusammen mit '%s' verwendet werden" + msgid "Nothing new to pack." msgstr "Nichts Neues zum Packen." #, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "Pack-Präfix %s fängt nicht mit objdir %s an" - -#, c-format msgid "renaming pack to '%s' failed" msgstr "Umbenennung des Pakets in '%s' fehlgeschlagen" @@ -11535,6 +11583,77 @@ msgstr "--convert-graft-file erwartet keine Argumente" msgid "only one pattern can be given with -l" msgstr "Mit -l kann nur ein Muster angegeben werden" +msgid "need some commits to replay" +msgstr "zum erneuten Abspielen werden Commits benötigt" + +msgid "--onto and --advance are incompatible" +msgstr "--onto und --advance sind inkompatibel" + +msgid "all positive revisions given must be references" +msgstr "alle angegebenen positiven Commits müssen Referenzen sein" + +msgid "argument to --advance must be a reference" +msgstr "Argument für --advance muss eine Referenz sein" + +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "" +"kann Ziel nicht mit mehreren Quellen erweitern, da die Reihenfolge unklar " +"wäre" + +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "" +"kann nicht implizit bestimmen, ob es sich um eine --advance oder --onto " +"Operation handelt" + +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "" +"kann Ziel nicht mit mehreren Quell-Branches erweitern, da die Reihenfolge " +"unklar wäre" + +msgid "cannot implicitly determine correct base for --onto" +msgstr "kann nicht implizit die richtige Basis für --onto bestimmen" + +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(EXPERIMENTELL!) git replay ([--contained] --onto <neue-Basis> | --advance " +"<Branch>) <Commitbereich>..." + +msgid "make replay advance given branch" +msgstr "angegebenen Branch durch neues Abspielen erweitern" + +msgid "replay onto given commit" +msgstr "auf angegebenen Commit neu abspielen" + +msgid "advance all branches contained in revision-range" +msgstr "alle Branches erweitern, die in Commitbereich liegen" + +msgid "option --onto or --advance is mandatory" +msgstr "Option --onto oder --advance erforderlich" + +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "" +"einige Optionen für das Abgehen von Commits werden außer Kraft gesetzt, da " +"das '%s' Bit in 'struct rev_info' erzwungen wird" + +msgid "error preparing revisions" +msgstr "Fehler beim Vorbereiten der Commits" + +msgid "replaying down to root commit is not supported yet!" +msgstr "erneutes Abspielen bis zum Root-Commit wird noch nicht unterstützt!" + +msgid "replaying merge commits is not supported yet!" +msgstr "erneutes Abspielen von Merge-Commits wird noch nicht unterstützt!" + msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" msgstr "" @@ -11746,18 +11865,12 @@ msgstr "--prefix benötigt ein Argument" msgid "unknown mode for --abbrev-ref: %s" msgstr "unbekannter Modus für --abbrev-ref: %s" -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden kann nicht zusammen mit --branches verwendet werden" - -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden kann nicht zusammen mit --tags verwendet werden" - -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden kann nicht zusammen mit --remotes verwendet werden" - msgid "this operation must be run in a work tree" msgstr "Diese Operation muss in einem Arbeitsverzeichnis ausgeführt werden." +msgid "Could not read the index" +msgstr "Konnte den Index nicht lesen" + #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "unbekannter Modus für --show-object-format: %s" @@ -12107,23 +12220,44 @@ msgid "Unknown hash algorithm" msgstr "Unbekannter Hash-Algorithmus" msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<Muster>...]" +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<Referenz>...]" + msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<Muster>]" +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <Referenz>" + +msgid "reference does not exist" +msgstr "Referenz nicht vorhanden" + +msgid "failed to look up reference" +msgstr "Fehler beim Nachschlagen der Referenz" + msgid "only show tags (can be combined with heads)" msgstr "nur Tags anzeigen (kann mit \"heads\" kombiniert werden)" msgid "only show heads (can be combined with tags)" msgstr "nur Branches anzeigen (kann mit \"tags\" kombiniert werden)" +msgid "check for reference existence without resolving" +msgstr "Prüfung auf Vorhandensein einer Referenz, ohne diese aufzulösen" + msgid "stricter reference checking, requires exact ref path" msgstr "strengere Referenzprüfung, erfordert exakten Referenzpfad" @@ -12973,6 +13107,9 @@ msgstr "" "shallow] [--reference <Repository>] [--recursive] [--[no-]single-branch] " "[--] [<Pfad>...]" +msgid "Failed to resolve HEAD as a valid ref." +msgstr "Konnte HEAD nicht als gültige Referenz auflösen." + msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<Optionen>] [<Pfad>...]" @@ -13456,6 +13593,9 @@ msgstr "(für Fremdprogramme) keine gespeicherten, nicht aufgelöste Konflikte" msgid "write index in this format" msgstr "Index-Datei in diesem Format schreiben" +msgid "report on-disk index format version" +msgstr "Bericht über die Version des Indexformats auf der Festplatte" + msgid "enable or disable split index" msgstr "aufgeteilten Index aktivieren oder deaktivieren" @@ -13482,6 +13622,14 @@ msgstr "Dateien als \"fsmonitor valid\" markieren" msgid "clear fsmonitor valid bit" msgstr "\"fsmonitor valid\"-Bit löschen" +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "index-version: war %d, wurde auf %d gesetzt" + msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -13643,33 +13791,29 @@ msgstr "Kein möglicher Quell-Branch, der auf '--orphan' schließen lässt" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan -b %s %s\n" msgstr "" -"Wenn Sie ein Arbeitsverzeichnis erstellen möchten, um einen neuen verwaisten " -"Branch\n" -"(Branch ohne Commits) für dieses Repository zu erstellen, können Sie dies " -"mit\n" -"der Option --orphan tun:\n" +"Wenn Sie ein Arbeitsverzeichnis erstellen möchten, welches einen neuen\n" +"ungeborenen Branch (Branch ohne Commits) für dieses Repository erzeugt,\n" +"können Sie dies mit der Option --orphan tun:\n" "\n" " git worktree add --orphan -b %s %s\n" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan %s\n" msgstr "" -"Wenn Sie ein Arbeitsverzeichnis erstellen möchten, um einen neuen verwaisten " -"Branch\n" -"(Branch ohne Commits) für dieses Repository zu erstellen, können Sie dies " -"mit\n" -"der Option --orphan tun:\n" +"Wenn Sie ein Arbeitsverzeichnis erstellen möchten, welches einen neuen\n" +"ungeborenen Branch (Branch ohne Commits) für dieses Repository erzeugt,\n" +"können Sie dies mit der Option --orphan tun:\n" "\n" " git worktree add --orphan %s\n" @@ -13732,6 +13876,10 @@ msgid "initializing" msgstr "initialisiere" #, c-format +msgid "could not find created worktree '%s'" +msgstr "konnte erstelltes Arbeitsverzeichnis '%s' nicht finden" + +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "Bereite Arbeitsverzeichnis vor (neuer Branch '%s')" @@ -13763,7 +13911,7 @@ msgstr "" msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" "Es gibt keine lokalen oder entfernten Referenzen, obwohl mindestens ein " "Remote-Repository\n" @@ -13771,10 +13919,6 @@ msgstr "" "Referenz zu überschreiben\n" "oder rufen Sie diese zuerst ab" -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "'%s' und '%s' können nicht zusammen verwendet werden" - msgid "checkout <branch> even if already checked out in other worktree" msgstr "" "<Branch> auschecken, auch wenn dieser bereits in einem anderen " @@ -13786,8 +13930,8 @@ msgstr "neuen Branch erstellen" msgid "create or reset a branch" msgstr "Branch erstellen oder umsetzen" -msgid "create unborn/orphaned branch" -msgstr "ungeborenen/verwaisten Branch erstellen" +msgid "create unborn branch" +msgstr "ungeborenen Branch erzeugen" msgid "populate the new working tree" msgstr "das neue Arbeitsverzeichnis auschecken" @@ -13812,11 +13956,8 @@ msgstr "" "die Optionen '%s', '%s' und '%s' können nicht gemeinsam verwendet werden" #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "die Optionen '%s' und '%s' können nicht gemeinsam verwendet werden" - -msgid "<commit-ish>" -msgstr "<Commit-Angabe>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "Option '%s' und commit-ish können nicht gemeinsam verwendet werden" msgid "added with --lock" msgstr "mit --lock hinzugefügt" @@ -14100,6 +14241,10 @@ msgid "terminating chunk id appears earlier than expected" msgstr "abschließende Chunk-ID erscheint eher als erwartet" #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "Chunk id %<PRIx32> nicht %d-byte-aligned" + +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "unzulässige(r) Chunk-Offset(s) %<PRIx64> und %<PRIx64>" @@ -14156,10 +14301,8 @@ msgstr "" msgid "Move objects and refs by archive" msgstr "Objekte und Referenzen über ein Archiv verteilen" -msgid "Provide content or type and size information for repository objects" -msgstr "" -"Inhalt oder Informationen zu Typ und Größe für Repository-Objekte " -"bereitstellen" +msgid "Provide contents or details of repository objects" +msgstr "Bereitstellung von Inhalten oder Details von Repository-Objekten" msgid "Display gitattributes information" msgstr "gitattributes Informationen darstellen" @@ -14465,6 +14608,11 @@ msgstr "ungepackte Objekte in einem Repository packen" msgid "Create, list, delete refs to replace objects" msgstr "Referenzen für ersetzende Objekte erstellen, auflisten, löschen" +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "" +"EXPERIMENTELL: Commits auf neuer Basis abspielen, funktioniert auch mit Bare-" +"Repositories" + msgid "Generates a summary of pending changes" msgstr "eine Übersicht über ausstehende Änderungen generieren" @@ -14591,8 +14739,8 @@ msgstr "die GPG-Signatur von Tags prüfen" msgid "Display version information about Git" msgstr "Versionsinformationen über Git anzeigen" -msgid "Show logs with difference each commit introduces" -msgstr "Logs mit dem Unterschied, den jeder Commit einführt, anzeigen" +msgid "Show logs with differences each commit introduces" +msgstr "Logs mit den Unterschieden anzeigen, den jeder Commit einführt" msgid "Manage multiple working trees" msgstr "mehrere Arbeitsverzeichnisse verwalten" @@ -14709,6 +14857,32 @@ msgstr "Ein Werkzeug zur Verwaltung großer Git-Repositories" msgid "commit-graph file is too small" msgstr "Commit-Graph-Datei ist zu klein" +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "Commit-Graph OID fanout Chunk hat die falsche Größe" + +msgid "commit-graph fanout values out of order" +msgstr "Commit-Graph fanout-Werte sind nicht in Ordnung" + +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "Commit-Graph OID Lookup Chunk hat die falsche Größe" + +msgid "commit-graph commit data chunk is wrong size" +msgstr "Commit-Graph Commit Daten Chunk hat die falsche Größe" + +msgid "commit-graph generations chunk is wrong size" +msgstr "Commit-Graph Generations Chunk hat die falsche Größe" + +msgid "commit-graph changed-path index chunk is too small" +msgstr "Commit-Graph changed-path Index Chunk ist zu klein" + +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "" +"ignoriere zu kleinen Chunk für geänderte Pfade (%<PRIuMAX> < %<PRIuMAX>) in " +"Commit-Graph-Datei" + #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "Commit-Graph-Signatur %X stimmt nicht mit Signatur %X überein" @@ -14725,9 +14899,22 @@ msgstr "Hash-Version des Commit-Graph %X stimmt nicht mit Version %X überein" msgid "commit-graph file is too small to hold %u chunks" msgstr "Commit-Graph-Datei ist zu klein, um %u Chunks zu enthalten" +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "Commit-Graph benötigter OID fanout Chunk fehlt oder ist beschädigt" + +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "Commit-Graph benötigter OID lookup Chunk fehlt oder ist beschädigt" + +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "" +"Commit-Graph erforderlicher Commit-Daten Chunk fehlt oder ist beschädigt" + msgid "commit-graph has no base graphs chunk" msgstr "Commit-Graph hat keinen Basis-Graph-Chunk" +msgid "commit-graph base graphs chunk is too small" +msgstr "Commit-Graph Basis-Graph-Chunk ist zu klein" + msgid "commit-graph chain does not match" msgstr "Commit-Graph Verkettung stimmt nicht überein" @@ -14735,6 +14922,9 @@ msgstr "Commit-Graph Verkettung stimmt nicht überein" msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "Anzahl der Commits im Basisgraph zu hoch: %<PRIuMAX>" +msgid "commit-graph chain file too small" +msgstr "Commit-Graph Chain-Datei zu klein" + #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" msgstr "Ungültige Commit-Graph Verkettung: Zeile '%s' ist kein Hash" @@ -14752,6 +14942,12 @@ msgstr "konnte Commit %s nicht finden" msgid "commit-graph requires overflow generation data but has none" msgstr "Commit-Graph erfordert Überlaufgenerierungsdaten, aber hat keine" +msgid "commit-graph overflow generation data is too small" +msgstr "Commit-Graph Überlaufgenerierungsdaten sind zu klein" + +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "commit-graph extra-edges Zeiger außerhalb der Grenzen" + msgid "Loading known commits in commit graph" msgstr "Lade bekannte Commits in Commit-Graph" @@ -14883,20 +15079,6 @@ msgid "commit-graph parent list for commit %s terminates early" msgstr "Commit-Graph Vorgänger-Liste für Commit %s endet zu früh" #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" -"Commit-Graph hat Generationsnummer null für Commit %s, aber sonst ungleich " -"null" - -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" -"Commit-Graph hat Generationsnummer ungleich null für Commit %s, aber sonst " -"null" - -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "Commit-Graph Erstellung für Commit %s ist %<PRIuMAX> < %<PRIuMAX>" @@ -14905,6 +15087,14 @@ msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>" msgstr "" "Commit-Datum für Commit %s in Commit-Graph ist %<PRIuMAX> != %<PRIuMAX>" +#, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "" +"Commit-Graph hat sowohl Null- als auch Nicht-Null-Generationen (z. B. " +"Commits '%s' und '%s')" + msgid "Verifying commits in commit graph" msgstr "Commit in Commit-Graph überprüfen" @@ -14933,6 +15123,11 @@ msgstr "" "\"git config advice.graftFileDeprecated false\" ausführen." #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "" +"Commit %s existiert im Commit-Graphen, aber nicht in der Objektdatenbank" + +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "" "Commit %s hat eine nicht vertrauenswürdige GPG-Signatur, angeblich von %s." @@ -15380,10 +15575,6 @@ msgstr "Referenz '%s' zeigt auf keinen Blob." msgid "unable to resolve config blob '%s'" msgstr "Konnte Blob '%s' für Konfiguration nicht auflösen." -#, c-format -msgid "failed to parse %s" -msgstr "Fehler beim Parsen von %s." - msgid "unable to parse command-line config" msgstr "" "Konnte die über die Befehlszeile angegebene Konfiguration nicht parsen." @@ -15863,9 +16054,6 @@ msgstr "Schreiben des Archivs fehlgeschlagen" msgid "--merge-base does not work with ranges" msgstr "--merge-base funktioniert nicht mit Bereichen" -msgid "--merge-base only works with commits" -msgstr "--merge-base funktioniert nur mit Commits" - msgid "unable to get HEAD" msgstr "konnte HEAD nicht bekommen" @@ -15927,6 +16115,10 @@ msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "Unbekannter Wert in Konfigurationsvariable 'diff.submodule': '%s'" #, c-format +msgid "unknown value for config '%s': %s" +msgstr "Unbekannter Wert für Konfiguration '%s': %s" + +#, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" @@ -16008,13 +16200,6 @@ msgstr "ungültiges --color-moved Argument: %s" msgid "invalid mode '%s' in --color-moved-ws" msgstr "ungültiger Modus '%s' in --color-moved-ws" -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"Option diff-algorithm akzeptiert: \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" - #, c-format msgid "invalid argument to %s" msgstr "ungültiges Argument für %s" @@ -16058,8 +16243,8 @@ msgstr "maschinenlesbare Ausgabe von --stat" msgid "output only the last line of --stat" msgstr "nur die letzte Zeile von --stat ausgeben" -msgid "<param1,param2>..." -msgstr "<Parameter1,Parameter2>..." +msgid "<param1>,<param2>..." +msgstr "<Parameter1>,<Parameter2>..." msgid "" "output the distribution of relative amount of changes for each sub-directory" @@ -16070,8 +16255,8 @@ msgstr "" msgid "synonym for --dirstat=cumulative" msgstr "Synonym für --dirstat=cumulative" -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "Synonym für --dirstat=files,Parameter1,Parameter2..." +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "Synonym für --dirstat=files,<Parameter1>,<Parameter2>..." msgid "warn if changes introduce conflict markers or whitespace errors" msgstr "" @@ -16254,12 +16439,6 @@ msgstr "Änderungen durch Nutzung des Algorithmus \"Patience Diff\" erzeugen" msgid "generate diff using the \"histogram diff\" algorithm" msgstr "Änderungen durch Nutzung des Algorithmus \"Histogram Diff\" erzeugen" -msgid "<algorithm>" -msgstr "<Algorithmus>" - -msgid "choose a diff algorithm" -msgstr "einen Algorithmus für Änderungen wählen" - msgid "<text>" msgstr "<Text>" @@ -17312,12 +17491,12 @@ msgstr "" "sind vorhanden:\n" "%s" -msgid "Failed to execute internal merge" +msgid "failed to execute internal merge" msgstr "Fehler bei Ausführung des internen Merges" #, c-format -msgid "Unable to add %s to database" -msgstr "Konnte %s nicht zur Datenbank hinzufügen" +msgid "unable to add %s to database" +msgstr "konnte %s nicht zur Datenbank hinzufügen" #, c-format msgid "Auto-merging %s" @@ -17775,6 +17954,19 @@ msgid "multi-pack-index OID fanout is of the wrong size" msgstr "Multi-Pack-Index OID fanout hat die falsche Größe" #, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"Ungültige oid fanout Reihenfolge: fanout[%d] = %<PRIx32> > %<PRIx32> = " +"fanout[%d]" + +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "multi-pack-index OID-Lookup-Chunk hat die falsche Größe" + +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "multi-pack-index Object-Offset-Chunk hat die falsche Größe" + +#, c-format msgid "multi-pack-index file %s is too small" msgstr "Multi-Pack-Index-Datei %s ist zu klein." @@ -17791,17 +17983,24 @@ msgstr "Multi-Pack-Index-Version %d nicht erkannt." msgid "multi-pack-index hash version %u does not match version %u" msgstr "Multi-Pack-Index Hash-Version %u stimmt nicht mit Version %u überein" -msgid "multi-pack-index missing required pack-name chunk" -msgstr "Multi-Pack-Index fehlt erforderlicher Pack-Namen Chunk" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "" +"multi-pack-index erforderlicher Pack-Name Chunk fehlt oder ist beschädigt" + +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "" +"multi-pack-index erforderlicher OID-Fanout-Chunk fehlt oder ist beschädigt" -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "Multi-Pack-Index fehlt erforderlicher OID fanout Chunk" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "" +"multi-pack-index erforderlicher OID Lookup Chunk fehlt oder ist beschädigt" -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "Multi-Pack-Index fehlt erforderlicher OID lookup Chunk" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "" +"multi-pack-index benötigte Objekt Offsets Chunk fehlt oder ist beschädigt" -msgid "multi-pack-index missing required object offsets chunk" -msgstr "Multi-Pack-Index fehlt erforderlicher Objekt offset Chunk" +msgid "multi-pack-index pack-name chunk is too short" +msgstr "multi-pack-index Pack-Name Chunk ist zu klein" #, c-format msgid "multi-pack-index pack names out of order: '%s' before '%s'" @@ -17811,10 +18010,20 @@ msgstr "Falsche Reihenfolge bei Multi-Pack-Index Pack-Namen: '%s' vor '%s'" msgid "bad pack-int-id: %u (%u total packs)" msgstr "Ungültige pack-int-id: %u (%u Pakete insgesamt)" +msgid "MIDX does not contain the BTMP chunk" +msgstr "MIDX enthält keinen BTMP-Chunk" + +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "konnte Bitmap-Paket nicht laden %<PRIu32>" + msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "" "Multi-Pack-Index speichert einen 64-Bit Offset, aber off_t ist zu klein" +msgid "multi-pack-index large offset out of bounds" +msgstr "multi-pack-index großer Offset außerhalb der Grenzen" + #, c-format msgid "failed to add packfile '%s'" msgstr "Fehler beim Hinzufügen von Packdatei '%s'" @@ -17893,13 +18102,6 @@ msgstr "Prüfsumme nicht korrekt" msgid "Looking for referenced packfiles" msgstr "Suche nach referenzierten Pack-Dateien" -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "" -"Ungültige oid fanout Reihenfolge: fanout[%d] = %<PRIx32> > %<PRIx32> = " -"fanout[%d]" - msgid "the midx contains no oid" msgstr "das midx enthält keine oid" @@ -18435,6 +18637,9 @@ msgstr "Multi-Pack-Bitmap fehlt erforderlicher Reverse-Index" msgid "could not open pack %s" msgstr "konnte Paket '%s' nicht öffnen" +msgid "could not determine MIDX preferred pack" +msgstr "konnte das von MIDX bevorzugte Paket nicht ermitteln" + #, c-format msgid "preferred pack (%s) is invalid" msgstr "bevorzugtes Paket (%s) ist ungültig" @@ -18458,6 +18663,12 @@ msgstr "" "fehlerhafte ewah-Bitmap: abgeschnittener Header für Bitmap des Commits \"%s\"" #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "" +"Paket kann nicht geladen werden: '%s', Deaktivierung der Paket-" +"Wiederverwendung" + +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "Objekt '%s' nicht im Typ Bitmaps gefunden" @@ -18545,6 +18756,12 @@ msgstr "ungültige Prüfsumme" msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "ungültige rev-index Position bei %<PRIu64>: %<PRIu32> != %<PRIu32>" +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "multi-pack-index Reverse-Index Chunk hat die falsche Größe" + +msgid "could not determine preferred pack" +msgstr "konnte das bevorzugte Paket nicht bestimmen" + msgid "cannot both write and verify reverse index" msgstr "" "Reverse-Index kann nicht gleichzeitig geschrieben und verifiziert werden" @@ -18597,14 +18814,6 @@ msgid "%s requires a value" msgstr "%s erfordert einen Wert." #, c-format -msgid "%s is incompatible with %s" -msgstr "%s ist inkompatibel mit %s." - -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s: inkompatibel mit etwas anderem" - -#, c-format msgid "%s takes no value" msgstr "%s erwartet keinen Wert" @@ -18689,6 +18898,10 @@ msgstr " %s" msgid "-NUM" msgstr "-NUM" +#, c-format +msgid "opposite of --no-%s" +msgstr "Gegenteil von --no-%s" + msgid "expiry-date" msgstr "Verfallsdatum" @@ -18720,6 +18933,14 @@ msgstr "" "Mit der Option --pathspec-from-file sind Pfade durch NUL-Zeichen getrennt" #, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "falscher boolescher Wert von Umgebungsvariable '%s' für '%s'" + +#, c-format +msgid "failed to parse %s" +msgstr "Fehler beim Parsen von %s." + +#, c-format msgid "Could not make %s writable by group" msgstr "Konnte Gruppenschreibrecht für %s nicht setzen." @@ -18768,6 +18989,10 @@ msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s: 'literal' und 'glob' sind inkompatibel" #, c-format +msgid "'%s' is outside the directory tree" +msgstr "'%s' liegt außerhalb des Verzeichnisbaums" + +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s: '%s' liegt außerhalb des Repositories von '%s'" @@ -18926,10 +19151,6 @@ msgid "unable to add '%s' to index" msgstr "Konnte '%s' nicht dem Index hinzufügen." #, c-format -msgid "unable to stat '%s'" -msgstr "konnte '%s' nicht lesen" - -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "'%s' scheint eine Datei und ein Verzeichnis zu sein" @@ -19037,10 +19258,6 @@ msgid "failed to convert to a sparse-index" msgstr "Konvertierung zu einem Sparse-Index fehlgeschlagen" #, c-format -msgid "could not stat '%s'" -msgstr "Konnte '%s' nicht lesen." - -#, c-format msgid "unable to open git dir: %s" msgstr "konnte Git-Verzeichnis nicht öffnen: %s" @@ -19512,10 +19729,6 @@ msgid "cannot process '%s' and '%s' at the same time" msgstr "kann '%s' und '%s' nicht zur selben Zeit verarbeiten" #, c-format -msgid "could not remove reference %s" -msgstr "konnte Referenz %s nicht löschen" - -#, c-format msgid "could not delete reference %s: %s" msgstr "konnte Referenz %s nicht entfernen: %s" @@ -19709,16 +19922,13 @@ msgid "" "\n" "Neither worked, so we gave up. You must fully qualify the ref." msgstr "" -"Das angegebene Ziel ist kein vollständiger Referenzname (startet mit \"refs/" -"\").\n" -"Wir versuchten zu erraten, was Sie meinten, mit:\n" +"Das angegebene Ziel ist kein vollständiger Referenzname (startet mit\n" +"\"refs/\"). Wir versuchten zu erraten, was Sie meinten, mit:\n" "\n" "- Suche einer Referenz, die mit '%s' übereinstimmt, auf der Remote-Seite\n" -"- Prüfung, ob die versendete <Quelle> ('%s') eine Referenz in \"refs/{heads," -"tags}\"\n" -" ist, in dessen Falle wir einen entsprechenden refs/{heads,tags} Präfix " -"auf\n" -" der Remote-Seite hinzufügen würden.\n" +"- Prüfung, ob die versendete <Quelle> ('%s') eine Referenz in\n" +" \"refs/{heads,tags}/\" ist, in dessen Falle wir einen entsprechenden\n" +" refs/{heads,tags}/ Präfix auf der Remote-Seite hinzufügen würden.\n" "\n" "Keines hat funktioniert, sodass wir aufgegeben haben. Sie müssen die\n" "Referenz mit vollqualifizierten Namen angeben." @@ -20084,8 +20294,15 @@ msgstr "vollständiges Arbeitsverzeichnis beim Klonen erstellen" msgid "only download metadata for the branch that will be checked out" msgstr "lade nur Metadaten des Branches herunter, der ausgecheckt wird" -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [<Optionen>] [--] <Repository> [<Verzeichnis>]" +msgid "create repository within 'src' directory" +msgstr "Repository im Verzeichnis 'src' erstellen" + +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <Haupt-Branch>] [--full-clone]\n" +"\t[--[no-]src] <URL> [<Eintragung>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20136,12 +20353,28 @@ msgid "could not remove stale scalar.repo '%s'" msgstr "konnte veraltetes scalar.repo '%s' nicht entfernen" #, c-format -msgid "removing stale scalar.repo '%s'" -msgstr "entferne veraltetes scalar.repo '%s'" +msgid "removed stale scalar.repo '%s'" +msgstr "veraltetes scalar.repo '%s' entfernt" + +#, c-format +msgid "repository at '%s' has different owner" +msgstr "Repository bei '%s' hat anderen Eigentümer" #, c-format -msgid "git repository gone in '%s'" -msgstr "Git-Repository entfernt in '%s'" +msgid "repository at '%s' has a format issue" +msgstr "Repository bei '%s' hat ein Formatproblem" + +#, c-format +msgid "repository not found in '%s'" +msgstr "Kein Repository in '%s' gefunden" + +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"um dieses Repository von Scalar abzumelden, führen Sie aus\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" msgid "" "scalar run <task> [<enlistment>]\n" @@ -20552,10 +20785,6 @@ msgid "%s: cannot parse parent commit %s" msgstr "%s: kann Eltern-Commit %s nicht parsen" #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "Konnte '%s' nicht zu '%s' umbenennen." - -#, c-format msgid "could not revert %s... %s" msgstr "Konnte \"revert\" nicht auf %s... (%s) ausführen" @@ -20884,6 +21113,9 @@ msgstr "Beim Anwenden des automatischen Stash traten Konflikte auf." msgid "Autostash exists; creating a new stash entry." msgstr "Automatischer Stash existiert; ein neuer Stash-Eintrag wird erstellt." +msgid "autostash reference is a symref" +msgstr "Referenz für autostash ist eine symbolische Referenz" + msgid "could not detach HEAD" msgstr "konnte HEAD nicht loslösen" @@ -20917,14 +21149,14 @@ msgstr "" " git rebase --continue\n" #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "Rebase (%d/%d)%s" - -#, c-format msgid "Stopped at %s... %.*s\n" msgstr "Angehalten bei %s... %.*s\n" #, c-format +msgid "Rebasing (%d/%d)%s" +msgstr "Rebase (%d/%d)%s" + +#, c-format msgid "unknown command %d" msgstr "Unbekannter Befehl %d" @@ -21193,7 +21425,7 @@ msgstr "ignoriere Vorlage %s" #, c-format msgid "templates not found in %s" -msgstr "Keine Vorlagen in %s gefunden." +msgstr "keine Vorlagen in %s gefunden" #, c-format msgid "not copying templates from '%s': %s" @@ -21204,25 +21436,31 @@ msgid "invalid initial branch name: '%s'" msgstr "ungültiger initialer Branchname: '%s'" #, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "Neu-Initialisierung: --initial-branch=%s ignoriert" + +#, c-format msgid "unable to handle file type %d" msgstr "kann nicht mit Dateityp %d umgehen" #, c-format msgid "unable to move %s to %s" -msgstr "Konnte %s nicht nach %s verschieben" +msgstr "konnte %s nicht nach %s verschieben" msgid "attempt to reinitialize repository with different hash" msgstr "Versuch, das Repository mit einem anderen Hash zu reinitialisieren" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "" +"Versuch, das Repository mit einem anderen Referenzspeicherformat neu zu " +"initialisieren" + #, c-format msgid "%s already exists" msgstr "%s existiert bereits" #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "Neu-Initialisierung: --initial-branch=%s ignoriert" - -#, c-format msgid "Reinitialized existing shared Git repository in %s%s\n" msgstr "Bestehendes verteiltes Git-Repository in %s%s neuinitialisiert\n" @@ -21491,12 +21729,6 @@ msgstr "" "Anzahl der Einträge im Cache-Verzeichnis, die ungültig gemacht werden sollen " "(Standardwert 0)" -msgid "unhandled options" -msgstr "unbehandelte Optionen" - -msgid "error preparing revisions" -msgstr "Fehler beim Vorbereiten der Commits" - #, c-format msgid "commit %s is not marked reachable" msgstr "Commit %s ist nicht als erreichbar gekennzeichnet." @@ -21652,9 +21884,6 @@ msgstr "" msgid "invalid remote service path" msgstr "ungültiger Remote-Service Pfad." -msgid "operation not supported by protocol" -msgstr "die Operation wird von dem Protokoll nicht unterstützt" - #, c-format msgid "can't connect to subservice %s" msgstr "kann keine Verbindung zu Subservice %s herstellen" @@ -21785,10 +22014,6 @@ msgid "support for protocol v2 not implemented yet" msgstr "Unterstützung für Protokoll v2 noch nicht implementiert." #, c-format -msgid "unknown value for config '%s': %s" -msgstr "Unbekannter Wert für Konfiguration '%s': %s" - -#, c-format msgid "transport '%s' not allowed" msgstr "Übertragungsart '%s' nicht erlaubt." @@ -21841,6 +22066,9 @@ msgstr "bundle-uri Operation wird vom Protokoll nicht unterstützt" msgid "could not retrieve server-advertised bundle-uri list" msgstr "konnte die vom Server angekündigte bundle-uri-Liste nicht abrufen" +msgid "operation not supported by protocol" +msgstr "die Operation wird von dem Protokoll nicht unterstützt" + msgid "too-short tree object" msgstr "zu kurzes Tree-Objekt" @@ -22248,6 +22476,9 @@ msgstr "konnte nicht auf '%s' zugreifen" msgid "unable to get current working directory" msgstr "konnte aktuelles Arbeitsverzeichnis nicht bekommen" +msgid "unable to get random bytes" +msgstr "konnte keine Zufallsbytes abrufen" + msgid "Unmerged paths:" msgstr "Nicht zusammengeführte Pfade:" @@ -22726,6 +22957,10 @@ msgid "cannot %s: Your index contains uncommitted changes." msgstr "" "%s nicht möglich: Die Staging-Area enthält nicht committete Änderungen." +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "unbekannter Stil '%s' für '%s' angegeben" + msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" @@ -22930,13 +23165,13 @@ msgstr "" "möchten.\n" #, perl-format -msgid "Failed to open %s: %s" -msgstr "Fehler beim Öffnen von %s: %s" - -#, perl-format msgid "Failed to open %s.final: %s" msgstr "Fehler beim Öffnen von %s.final: %s" +#, perl-format +msgid "Failed to open %s: %s" +msgstr "Fehler beim Öffnen von %s: %s" + msgid "Summary email is empty, skipping it\n" msgstr "E-Mail mit Zusammenfassung ist leer, wird ausgelassen\n" @@ -21,6 +21,7 @@ # bypass | éviter d'utiliser # to checkout | extraire # cherry-pick | picorer +# chunk | tronçon # to commit | valider # commit-ish | commit ou apparenté # config file | fichier de configuration @@ -29,6 +30,7 @@ # debugging | débogage # to deflate | compresser # email | courriel +# enlistment | enrôlement # entry | élément # fanout | dispersion # fast-forward | avance rapide @@ -78,8 +80,8 @@ msgid "" msgstr "" "Project-Id-Version: git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-16 11:48+0200\n" -"PO-Revision-Date: 2023-08-16 11:49+0200\n" +"POT-Creation-Date: 2024-02-16 19:18+0100\n" +"PO-Revision-Date: 2024-02-16 19:19+0100\n" "Last-Translator: Cédric Malard <c.malard-git@valdun.net>\n" "Language-Team: Jean-Noël Avila <jn.avila@free.fr>\n" "Language: fr\n" @@ -1524,6 +1526,10 @@ msgid "Unexpected option --output" msgstr "Option --output inattendue" #, c-format +msgid "extra command line parameter '%s'" +msgstr "paramètre de commande supplémentaire '%s'" + +#, c-format msgid "Unknown archive format '%s'" msgstr "Format d'archive inconnu '%s'" @@ -1569,6 +1575,14 @@ msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "mauvais --attr-source ou GIT_ATTR_SOURCE" #, c-format +msgid "unable to stat '%s'" +msgstr "fstat de '%s' impossible" + +#, c-format +msgid "unable to read %s" +msgstr "impossible de lire %s" + +#, c-format msgid "Badly quoted content in file '%s': %s" msgstr "Contenu mal cité dans le fichier '%s' : %s" @@ -1855,8 +1869,8 @@ msgid "submodule '%s': cannot create branch '%s'" msgstr "sous-module '%s' : impossible de créer la branche '%s'" #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "'%s' est déjà extrait dans '%s'" +msgid "'%s' is already used by worktree at '%s'" +msgstr "'%s' est déjà utilisé par l'arbre-de-travail dans '%s'" msgid "git add [<options>] [--] <pathspec>..." msgstr "git add [<options>] [--] <chemin>..." @@ -1875,25 +1889,22 @@ msgstr "" "le réglage add.interactive.useBuiltin a été supprimé !\n" "Référez-vous à cette entrée dans 'git help config' pour plus de détails." -msgid "Could not read the index" -msgstr "Impossible de lire l'index" - -msgid "Could not write patch" -msgstr "Impossible d'écrire le patch" +msgid "could not read the index" +msgstr "impossible de lire l'index" msgid "editing patch failed" msgstr "échec de l'édition du patch" #, c-format -msgid "Could not stat '%s'" -msgstr "Stat de '%s' impossible" +msgid "could not stat '%s'" +msgstr "impossible de stat '%s'" -msgid "Empty patch. Aborted." -msgstr "Patch vide. Abandon." +msgid "empty patch. aborted" +msgstr "rustine vide. abandon" #, c-format -msgid "Could not apply '%s'" -msgstr "Impossible d'appliquer '%s'" +msgid "could not apply '%s'" +msgstr "impossible d'appliquer '%s'" msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" @@ -2027,6 +2038,9 @@ msgstr "" msgid "index file corrupt" msgstr "fichier d'index corrompu" +msgid "unable to write new index file" +msgstr "impossible d'écrire le nouveau fichier d'index" + #, c-format msgid "bad action '%s' for '%s'" msgstr "action invalide '%s' pour '%s'" @@ -2236,9 +2250,6 @@ msgstr "" "Vous pouvez lancer 'git rm' sur un fichier \"supprimé par eux\" pour " "accepter son état." -msgid "unable to write new index file" -msgstr "impossible d'écrire le nouveau fichier d'index" - #, c-format msgid "Could not parse object '%s'." msgstr "Impossible d'analyser l'objet '%s'." @@ -2257,10 +2268,6 @@ msgstr "" msgid "failed to read '%s'" msgstr "échec de la lecture de '%s'" -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "les options '%s=%s' et '%s=%s' ne peuvent pas être utilisées ensemble" - msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<options>] [(<mbox> | <Maildir>)...]" @@ -2414,7 +2421,7 @@ msgid "git archive: expected a flush" msgstr "git archive : vidage attendu" msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" "git bisect start [--term-{new,bad}=<terme> --term-{old,good}=<terme>] [--" @@ -2433,8 +2440,8 @@ msgstr "git bisect reset [<commit>]" msgid "git bisect replay <logfile>" msgstr "git bisect replay <fichier-journal>" -msgid "git bisect run <cmd>..." -msgstr "git bisect run <cmd>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <cmd> [<arg>...]" #, c-format msgid "cannot open file '%s' in mode '%s'" @@ -2861,44 +2868,46 @@ msgstr "git branch [<options>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" "suppression de la branche '%s' qui a été fusionnée dans\n" -" '%s', mais pas dans HEAD." +" '%s', mais pas encore dans HEAD" #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" -"branche '%s' non supprimée car elle n'a pas été fusionnée dans\n" -" '%s', même si elle est fusionnée dans HEAD." +"branche '%s' non supprimée car elle n'a pas encore été fusionnée dans\n" +" '%s', même si elle est fusionnée dans HEAD" #, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "Impossible de rechercher l'objet commit pour '%s'" +msgid "couldn't look up commit object for '%s'" +msgstr "impossible de rechercher l'objet commit pour '%s'" #, 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 "" -"La branche '%s' n'est pas totalement fusionnée.\n" -"Si vous souhaitez réellement la supprimer, lancez 'git branch -D %s'." +msgid "the branch '%s' is not fully merged" +msgstr "la branche '%s' n'est pas complètement fusionnée" + +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" +msgstr "Si vous souhaitez réellement la supprimer, lancez 'git branch -D %s'" -msgid "Update of config-file failed" -msgstr "Échec de la mise à jour du fichier de configuration" +msgid "update of config-file failed" +msgstr "échec de la mise à jour du fichier de configuration" msgid "cannot use -a with -d" msgstr "impossible d'utiliser -a avec -d" #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "Impossible de supprimer la branche '%s' extraite dans '%s'" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "" +"impossible de supprimer la branche '%s' utilisée par l'arbre-de-travail dans " +"'%s'" #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "branche de suivi '%s' non trouvée." +msgid "remote-tracking branch '%s' not found" +msgstr "branche de suivi '%s' non trouvée" #, c-format msgid "" @@ -2909,8 +2918,8 @@ msgstr "" "Avez-vous oublié --remote ?" #, c-format -msgid "branch '%s' not found." -msgstr "branche '%s' non trouvée." +msgid "branch '%s' not found" +msgstr "branche '%s' non trouvée" #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" @@ -2931,55 +2940,55 @@ msgid "HEAD (%s) points outside of refs/heads/" msgstr "HEAD (%s) pointe hors de refs/heads/" #, c-format -msgid "Branch %s is being rebased at %s" -msgstr "La branche %s est en cours de rebasage sur %s" +msgid "branch %s is being rebased at %s" +msgstr "la branche %s est en cours de rebasage sur %s" #, c-format -msgid "Branch %s is being bisected at %s" -msgstr "La branche %s est en cours de bissection sur %s" +msgid "branch %s is being bisected at %s" +msgstr "la branche %s est en cours de bissection sur %s" #, c-format msgid "HEAD of working tree %s is not updated" msgstr "la HEAD de la copie de travail %s n'est pas mise à jour" #, c-format -msgid "Invalid branch name: '%s'" -msgstr "Nom de branche invalide : '%s'" +msgid "invalid branch name: '%s'" +msgstr "nom de branche invalide : '%s'" #, c-format -msgid "No commit on branch '%s' yet." -msgstr "Aucun commit sur la branche '%s'." +msgid "no commit on branch '%s' yet" +msgstr "aucun commit encore sur la branche '%s'" #, c-format -msgid "No branch named '%s'." -msgstr "Aucune branche nommée '%s'." +msgid "no branch named '%s'" +msgstr "aucune branche nommée '%s'" -msgid "Branch rename failed" -msgstr "Échec de renommage de la branche" +msgid "branch rename failed" +msgstr "échec de renommage de la branche" -msgid "Branch copy failed" -msgstr "Échec de copie de la branche" +msgid "branch copy failed" +msgstr "échec de copie de la branche" #, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "Création d'une copie d'une branche mal nommée '%s'" +msgid "created a copy of a misnamed branch '%s'" +msgstr "création d'une copie d'une branche mal nommée '%s'" #, c-format -msgid "Renamed a misnamed branch '%s' away" -msgstr "Renommage d'une branche mal nommée '%s'" +msgid "renamed a misnamed branch '%s' away" +msgstr "renommage d'une branche mal nommée '%s'" #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "La branche a été renommée en %s, mais HEAD n'est pas mise à jour !" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "la branche a été renommée en %s, mais HEAD n'est pas mise à jour" -msgid "Branch is renamed, but update of config-file failed" +msgid "branch is renamed, but update of config-file failed" msgstr "" -"La branche est renommée, mais la mise à jour du fichier de configuration a " +"la branche est renommée, mais la mise à jour du fichier de configuration a " "échoué" -msgid "Branch is copied, but update of config-file failed" +msgid "branch is copied, but update of config-file failed" msgstr "" -"La branche est copiée, mais la mise à jour du fichier de configuration a " +"la branche est copiée, mais la mise à jour du fichier de configuration a " "échoué" #, c-format @@ -3094,8 +3103,8 @@ msgstr "parcourir récursivement les sous-modules" msgid "format to use for the output" msgstr "format à utiliser pour la sortie" -msgid "Failed to resolve HEAD as a valid ref." -msgstr "Échec de résolution de HEAD comme référence valide." +msgid "failed to resolve HEAD as a valid ref" +msgstr "échec de résolution de HEAD comme référence valide" msgid "HEAD not found below refs/heads!" msgstr "HEAD non trouvée sous refs/heads !" @@ -3113,17 +3122,17 @@ msgstr "--recurse-submodules ne peut être utilisé que pour créer des branches msgid "branch name required" msgstr "le nom de branche est requis" -msgid "Cannot give description to detached HEAD" -msgstr "Impossible de décrire une HEAD détachée" +msgid "cannot give description to detached HEAD" +msgstr "impossible de décrire une HEAD détachée" msgid "cannot edit description of more than one branch" msgstr "impossible d'éditer la description de plus d'une branche" -msgid "cannot copy the current branch while not on any." -msgstr "impossible de copier la branche actuelle, il n'y en a pas." +msgid "cannot copy the current branch while not on any" +msgstr "impossible de copier la branche actuelle, il n'y en a pas" -msgid "cannot rename the current branch while not on any." -msgstr "impossible de renommer la branche actuelle, il n'y en a pas." +msgid "cannot rename the current branch while not on any" +msgstr "impossible de renommer la branche actuelle, il n'y en a pas" msgid "too many branches for a copy operation" msgstr "trop de branches pour une opération de copie" @@ -3136,10 +3145,10 @@ msgstr "trop d'arguments pour spécifier une branche amont" #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." +"could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" "impossible de spécifier une branche amont de HEAD par %s qui ne pointe sur " -"aucune branche." +"aucune branche" #, c-format msgid "no such branch '%s'" @@ -3152,29 +3161,29 @@ msgstr "la branche '%s' n'existe pas" msgid "too many arguments to unset upstream" msgstr "trop d'arguments pour désactiver un amont" -msgid "could not unset upstream of HEAD when it does not point to any branch." +msgid "could not unset upstream of HEAD when it does not point to any branch" msgstr "" "impossible de désactiver une branche amont de HEAD quand elle ne pointe sur " -"aucune branche." +"aucune branche" #, c-format -msgid "Branch '%s' has no upstream information" -msgstr "La branche '%s' n'a aucune information de branche amont" +msgid "branch '%s' has no upstream information" +msgstr "la branche '%s' n'a aucune information de branche amont" msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"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 "" -"Les options -a et -r de 'git branch' n'ont pas de sens avec un nom de " +"les options -a et -r de 'git branch' n'ont pas de sens avec un nom de " "branche.\n" "Vouliez-vous plutôt dire -a|-r --list <motif> ?" msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." +"'--set-upstream-to' instead" msgstr "" "l'option '--set-upstream' est obsolète. Utilisez '--track' ou '--set-" -"upstream-to' à la place." +"upstream-to' à la place" msgid "git version:\n" msgstr "version git ::\n" @@ -3252,6 +3261,10 @@ msgid "specify a strftime format suffix for the filename(s)" msgstr "spécifier une suffixe au format strftime pour le(s) nom(s) de fichier" #, c-format +msgid "unknown argument `%s'" +msgstr "argument inconnu '%s'" + +#, c-format msgid "could not create leading directories for '%s'" msgstr "impossible de créer les répertoires de premier niveau pour '%s'" @@ -3358,6 +3371,13 @@ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objet>" msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<chemin|arbresque> | --path=<chemin|arbresque> <rev>]" + +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -3368,13 +3388,6 @@ msgstr "" " [--buffer] [--follow-symlinks] [--unordered]\n" " [--textconv | --filters] [-Z]" -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<chemin|arbresque> | --path=<chemin|arbresque> <rev>]" - msgid "Check object existence or emit object contents" msgstr "Vérifie l'existence d'un objet ou émettre le contenu de l'objet" @@ -3676,6 +3689,12 @@ msgid "'%s' or '%s' cannot be used with %s" msgstr "'%s' ou '%s' ne peut pas être utilisé avec %s" #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "" +"'%s', '%s' ou '%s' ne peuvent pas être utilisés lors de l'extraction d'un " +"arbre" + +#, c-format msgid "path '%s' is unmerged" msgstr "le chemin '%s' n'est pas fusionné" @@ -3930,8 +3949,8 @@ msgstr "forcer l'extraction (laisser tomber les modifications locales)" msgid "new-branch" msgstr "nouvelle branche" -msgid "new unparented branch" -msgstr "nouvelle branche sans parent" +msgid "new unborn branch" +msgstr "nouvelle branche non née" msgid "update ignored files (default)" msgstr "mettre à jour les fichiers ignorés (par défaut)" @@ -4185,9 +4204,6 @@ msgstr "" "clean.requireForce à true par défaut et ni -i, -n ou -f fourni ; refus de " "nettoyer" -msgid "-x and -X cannot be used together" -msgstr "-x et -X ne peuvent pas être utilisés ensemble" - msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<options>] [--] <dépôt> [<répertoire>]" @@ -4278,6 +4294,9 @@ msgstr "gitdir" msgid "separate git dir from working tree" msgstr "séparer le répertoire git de la copie de travail" +msgid "specify the reference format to use" +msgstr "spécifier le format de réference à utiliser" + msgid "key=value" msgstr "clé=valeur" @@ -4400,12 +4419,9 @@ msgstr "Trop d'arguments." msgid "You must specify a repository to clone." msgstr "Vous devez spécifier un dépôt à cloner." -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "" -"--bundle-uri est incompatible avec --depth, --shallow-since, et --shallow-" -"exclude" +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "Format de stockage de réf inconnu '%s'" #, c-format msgid "repository '%s' does not exist" @@ -4539,14 +4555,14 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <rép>] [--append]\n" " [--split[=<stratégie>]] [--reachable | --stdin-packs " "| --stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <options de division>" +" <options-de-division>" msgid "dir" msgstr "répertoire" @@ -4563,6 +4579,10 @@ msgid "Could not open commit-graph '%s'" msgstr "Impossible d'ouvrir le graphe de commit '%s'" #, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "impossible d'ouvrir le graphe de commit '%s'" + +#, c-format msgid "unrecognized --split argument, %s" msgstr "argument de --split non reconnu, %s" @@ -4762,9 +4782,6 @@ msgstr "impossible de mettre à jour l'index temporaire" msgid "Failed to update main cache tree" msgstr "Impossible de mettre à jour l'arbre de cache principal" -msgid "unable to write new_index file" -msgstr "impossible d'écrire le fichier new_index" - msgid "cannot do a partial commit during a merge." msgstr "impossible de faire une validation partielle pendant une fusion." @@ -5174,11 +5191,11 @@ msgstr "" msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" -"le dépôt a été mis à jour, mais impossible d'écrire le fichier\n" -"new_index. Vérifiez que le disque n'est pas plein ou que le quota\n" +"le dépôt a été mis à jour, mais impossible d'écrire le nouveau fichier\n" +"d'index. Vérifiez que le disque n'est pas plein ou que le quota\n" "n'a pas été dépassé, puis lancez \"git restore --staged :/\" pour réparer." msgid "git config [<options>]" @@ -6644,6 +6661,9 @@ msgstr "élaguer les objets non référencés" msgid "pack unreferenced objects separately" msgstr "empaqueter les objets non référencés séparément" +msgid "with --cruft, limit the size of new cruft packs" +msgstr "avec --cruft, limiter la taille des nouveaux paquets déchets" + msgid "be more thorough (increased runtime)" msgstr "être plus consciencieux (durée de traitement allongée)" @@ -6823,12 +6843,6 @@ msgstr "" msgid "'crontab' died" msgstr "'crontab' est mort" -msgid "failed to start systemctl" -msgstr "échec du démarrage de systemctl" - -msgid "failed to run systemctl" -msgstr "échec pour lancer systemctl" - #, c-format msgid "failed to delete '%s'" msgstr "échec de la suppression de '%s'" @@ -6837,6 +6851,12 @@ msgstr "échec de la suppression de '%s'" msgid "failed to flush '%s'" msgstr "échec du flush de '%s'" +msgid "failed to start systemctl" +msgstr "échec du démarrage de systemctl" + +msgid "failed to run systemctl" +msgstr "échec pour lancer systemctl" + #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "argument '%s' de --scheduler non reconnu" @@ -6862,6 +6882,9 @@ msgstr "planificateur" msgid "scheduler to trigger git maintenance run" msgstr "planificateur qui lancera les maintenances git" +msgid "failed to set up maintenance schedule" +msgstr "impossible de mettre en place la planification de maintenance" + msgid "failed to add repo to global config" msgstr "échec de l'ajout du dépôt à la config globale" @@ -6893,6 +6916,10 @@ msgid "unable to read tree (%s)" msgstr "impossible de lire l'arbre (%s)" #, c-format +msgid "unable to read tree %s" +msgstr "impossible de lire l'arbre %s" + +#, c-format msgid "unable to grep from object of type %s" msgstr "impossible de faire un grep sur un objet de type %s" @@ -6936,8 +6963,8 @@ msgstr "traiter les fichiers binaires avec les filtres textconv" msgid "search in subdirectories (default)" msgstr "rechercher dans les sous-répertoires (défaut)" -msgid "descend at most <depth> levels" -msgstr "descendre au plus de <profondeur> dans l'arborescence" +msgid "descend at most <n> levels" +msgstr "descendre au plus de <n> niveaux" msgid "use extended POSIX regular expressions" msgstr "utiliser des expressions régulières étendues POSIX" @@ -7311,10 +7338,6 @@ msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "COLLISION SHA1 TROUVÉE AVEC %s !" #, c-format -msgid "unable to read %s" -msgstr "impossible de lire %s" - -#, c-format msgid "cannot read existing object info %s" msgstr "impossible de lire l'information existante de l'objet %s" @@ -7455,12 +7478,14 @@ msgstr "erreur de fsck dans les objets paquets" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" -"git init [-q | --quiet] [--bare] [--template=<répertoire-modèle>]\n" -" [--separate-git-dir <rép-git>] [--object-format=<format>]\\n\"\n" -" [-b <nom-de-branche> | --initial-branch=<nom-de-branche>]\\n\"\n" +"git init [-q | --quiet] [--bare] [--template=<répertoire-de-modèles>]\n" +" [--separate-git-dir <rép-git>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" +" [-b <nom-de-branch> | --initial-branch=<nom-de-branche>]\n" " [--shared[=<permissions>]] [<répertoire>]" msgid "permissions" @@ -7503,11 +7528,12 @@ msgstr "--separate-git-dir est incompatible avec un dépôt nu" msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <symbole>[(=|:)<valeur>])...]\n" +" [(--trailer (<clé>|<alias-de-clé>)" +"[(=|:)<valeur>])...]\n" " [--parse] [<fichier>...]" msgid "edit files in place" @@ -7516,6 +7542,9 @@ msgstr "éditer les fichiers sur place" msgid "trim empty trailers" msgstr "éliminer les lignes de fin vides" +msgid "placement" +msgstr "placement" + msgid "where to place the new trailer" msgstr "où placer les nouvelles lignes terminales" @@ -7528,17 +7557,19 @@ msgstr "action si les lignes terminales manquent" msgid "output only the trailers" msgstr "éliminer les lignes terminales vides" -msgid "do not apply config rules" -msgstr "ne pas appliquer les règles de la configuration" +msgid "do not apply trailer.* configuration variables" +msgstr "ne pas appliquer les variables de configuration trailer.*" -msgid "join whitespace-continued values" -msgstr "joindre les valeurs continuées avec des caractères blancs" +msgid "reformat multiline trailer values as single-line values" +msgstr "" +"reformatter les valeurs de ligne terminales multi-lignes en valeurs sur une " +"seule ligne" -msgid "set parsing options" -msgstr "paramètres d'analyse" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "alias pour --only-trailers --only-input --unfold" -msgid "do not treat --- specially" -msgstr "ne pas traiter spécialement ---" +msgid "do not treat \"---\" as the end of input" +msgstr "ne pas traiter \"---\" comme la fin d'entrée" msgid "trailer(s) to add" msgstr "ligne(s) de fin à ajouter" @@ -7628,6 +7659,10 @@ msgstr "exactement une plage nécessaire" msgid "not a range" msgstr "ceci n'est pas une plage" +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "lecture du fichier de description de branche '%s' impossible" + msgid "cover letter needs email format" msgstr "la lettre de motivation doit être au format courriel" @@ -7734,6 +7769,9 @@ msgstr "" "générer des parties de la lettre d'introduction à partir de la description " "de la branche" +msgid "use branch description from file" +msgstr "utiliser la description de branche dans le fichier" + msgid "use [<prefix>] instead of [PATCH]" msgstr "utiliser [<préfixe>] au lieu de [PATCH]" @@ -8177,9 +8215,19 @@ msgstr "" "git merge-file [<options>] [-L <nom1> [-L <orig> [-L <nom2>]]] <fichier1> " "<fichier-orig> <fichier2>" +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"l'option diff-algorithm accept \"myers\", \"minimal\", \"patience\" et " +"\"histogram\"" + msgid "send results to standard output" msgstr "envoyer les résultats sur la sortie standard" +msgid "use object IDs instead of filenames" +msgstr "utiliser les IDs d'objet au lieu de noms de fichier" + msgid "use a diff3 based merge" msgstr "utiliser une fusion basée sur diff3" @@ -8195,6 +8243,12 @@ msgstr "pour les conflits, utiliser leur version (their)" msgid "for conflicts, use a union version" msgstr "pour les conflits, utiliser l'ensemble des versions" +msgid "<algorithm>" +msgstr "<algorithme>" + +msgid "choose a diff algorithm" +msgstr "choisir un algorithme de différence" + msgid "for conflicts, use this marker size" msgstr "pour les conflits, utiliser cette taille de marqueur" @@ -8205,6 +8259,13 @@ msgid "set labels for file1/orig-file/file2" msgstr "définir les labels pour fichier1/fichier-orig/fichier2" #, c-format +msgid "object '%s' does not exist" +msgstr "l'objet '%s' n'existe pas" + +msgid "Could not write object file" +msgstr "impossible d'écrire le fichier d'objet" + +#, c-format msgid "unknown option %s" msgstr "option inconnue %s" @@ -8265,11 +8326,18 @@ msgstr "réaliser des fusions multiples, une par ligne d'entrée" msgid "specify a merge-base for the merge" msgstr "spécifier une base de fusion pour la fusion" +msgid "option=value" +msgstr "option=valeur" + +msgid "option for selected merge strategy" +msgstr "option pour la stratégie de fusion sélectionnée" + msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge est incompatible avec d'autres options" -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base est incompatible avec --stdin" +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "option de stratégie inconnue : -X%s" #, c-format msgid "malformed input line: '%s'." @@ -8339,12 +8407,6 @@ msgstr "stratégie" msgid "merge strategy to use" msgstr "stratégie de fusion à utiliser" -msgid "option=value" -msgstr "option=valeur" - -msgid "option for selected merge strategy" -msgstr "option pour la stratégie de fusion sélectionnée" - msgid "merge commit message (for a non-fast-forward merge)" msgstr "" "message de validation de la fusion (pour une fusion sans avance rapide)" @@ -8406,10 +8468,6 @@ msgid "Not handling anything other than two heads merge." msgstr "Impossible de gérer autre chose que la fusion de deux têtes." #, c-format -msgid "unknown strategy option: -X%s" -msgstr "option de stratégie inconnue : -X%s" - -#, c-format msgid "unable to write %s" msgstr "impossible d'écrire %s" @@ -8710,8 +8768,8 @@ msgstr "la destination existe" msgid "can not move directory into itself" msgstr "impossible de déplacer un répertoire dans lui-même" -msgid "cannot move directory over file" -msgstr "impossible de déplacer un répertoire sur un fichier" +msgid "destination already exists" +msgstr "la destination existe déjà " msgid "source directory is empty" msgstr "le répertoire source est vide" @@ -9228,6 +9286,10 @@ msgid "inconsistency with delta count" msgstr "inconsistance dans le compte de delta" #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "valeur invalide de pack.allowPackReuse : '%s'" + +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -9471,9 +9533,6 @@ msgstr "la taille limite minimale d'un paquet est 1 MiB" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin ne peut pas être utilisé pour construire un paquet indexable" -msgid "cannot use --filter without --stdout" -msgstr "impossible d'utiliser --filter sans --stdout" - msgid "cannot use --filter with --stdin-packs" msgstr "impossible d'utiliser --filter avec --stdin-packs" @@ -9487,19 +9546,16 @@ msgstr "impossible d'utiliser une liste interne de révisions avec --cruft" msgid "cannot use --stdin-packs with --cruft" msgstr "impossible d'utiliser --stdin-packs avec --cruft" -msgid "cannot use --max-pack-size with --cruft" -msgstr "impossible d'utiliser --max-pack-size avec --cruft" - msgid "Enumerating objects" msgstr "Énumération des objets" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "Total %<PRIu32> (delta %<PRIu32>), réutilisés %<PRIu32> (delta %<PRIu32>), " -"réutilisés du pack %<PRIu32>" +"réutilisés du paquet %<PRIu32> (depuis %<PRIuMAX>)" msgid "" "'git pack-redundant' is nominated for removal.\n" @@ -10488,16 +10544,6 @@ msgstr "" msgid "switch `C' expects a numerical value" msgstr "l'option `C' attend un valeur numérique" -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy requiert --merge ou --interactive" - -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "" -"les options d'application sont incompatibles avec rebase.autoSquash. " -"Considérez l'ajout de --no-autosquash" - msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -11213,6 +11259,10 @@ msgstr "impossible de fermer le fichier temporaire d'instantané des réfs" msgid "could not remove stale bitmap: %s" msgstr "impossible de revenir la bitmap obsolète : %s" +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "le préfixe %s ne commence pas avec objdir %s" + msgid "pack everything in a single pack" msgstr "empaqueter tout dans un seul paquet" @@ -11290,17 +11340,20 @@ msgstr "écrire un index de multi-paquet des paquets résultants" msgid "pack prefix to store a pack containing pruned objects" msgstr "préfixe de paquet pour stocker un paquet contenant les objets élagués" +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "préfixe de paquet pour stocker un paquet contenant les objets filtrés" + msgid "cannot delete packs in a precious-objects repo" msgstr "impossible de supprimer les paquets dans un dépôt d'objets précieux" +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "l'option '%s' ne peut être utilisé qu'avec '%s'" + msgid "Nothing new to pack." msgstr "Rien de neuf à empaqueter." #, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "le préfixe %s ne commence pas avec objdir %s" - -#, c-format msgid "renaming pack to '%s' failed" msgstr "le renommage du paquet en '%s' a échoué" @@ -11500,6 +11553,77 @@ msgstr "--convert-graft-file ne supporte aucun argument" msgid "only one pattern can be given with -l" msgstr "-l n'accepte qu'un motifs" +msgid "need some commits to replay" +msgstr "commits requis pour pouvoir rejouer" + +msgid "--onto and --advance are incompatible" +msgstr "--onto et --advance sont incompatibles" + +msgid "all positive revisions given must be references" +msgstr "toutes les révisions positives fournies doivent être des références" + +msgid "argument to --advance must be a reference" +msgstr "l'argument de --advance doit être une référence" + +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "" +"impossible d'avancer la cible avec des sources multiples parce l'ordre ne " +"serait pas total" + +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "" +"impossible de déterminer implicitement s'il y a une opération --advance ou --" +"onto" + +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "" +"impossible d'avancer la cible sur des branches sources multiples parce que " +"l'ordre ne serait pas total" + +msgid "cannot implicitly determine correct base for --onto" +msgstr "impossible de déterminer implicitement une base correcte pour --onto" + +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <nouvelle-base> | --advance " +"<branche>) <plage-de-révision>..." + +msgid "make replay advance given branch" +msgstr "faire rejouer en avançant la branche indiquée" + +msgid "replay onto given commit" +msgstr "rejouer par-dessus le commit indiqué" + +msgid "advance all branches contained in revision-range" +msgstr "avancer toutes les branches contenues dans la plage-de-révisions" + +msgid "option --onto or --advance is mandatory" +msgstr "une option --onto ou --advance est obligatoire" + +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "" +"certaines options de parcours de révs seront surchargées car le bit '%s' " +"dans 'struct rev_info' sera forcé" + +msgid "error preparing revisions" +msgstr "erreur lors de la préparation des révisions" + +msgid "replaying down to root commit is not supported yet!" +msgstr "rejouer jusqu'au commit racine n'est pas encore géré !" + +msgid "replaying merge commits is not supported yet!" +msgstr "rejouer des commits de fusion n'est pas encore géré !" + msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" msgstr "" @@ -11711,18 +11835,12 @@ msgstr "--prefix exige un argument" msgid "unknown mode for --abbrev-ref: %s" msgstr "mode inconnu pour --abbrev-ref : %s" -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden ne peut être utilisé avec --branches" - -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden ne peut pas être utilisé avec --tags" - -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden ne peut pas être utilisé avec --remotes" - msgid "this operation must be run in a work tree" msgstr "cette opération doit être effectuée dans un arbre de travail" +msgid "Could not read the index" +msgstr "Impossible de lire l'index" + #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "mode inconnu pour --show-object-format : %s" @@ -12072,23 +12190,44 @@ msgid "Unknown hash algorithm" msgstr "Algorithme d'empreinte inconnu" msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<motif>...]" +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" + msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<motif>]" +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <réf>" + +msgid "reference does not exist" +msgstr "la référence n'existe pas" + +msgid "failed to look up reference" +msgstr "échec de la recherche de la référence" + msgid "only show tags (can be combined with heads)" msgstr "afficher seulement les étiquettes (peut être combiné avec heads)" msgid "only show heads (can be combined with tags)" msgstr "afficher seulement les têtes (peut être combiné avec tags)" +msgid "check for reference existence without resolving" +msgstr "vérifier l'existence de la référence sans la résoudre" + msgid "stricter reference checking, requires exact ref path" msgstr "" "vérification de référence plus stricte, nécessite un chemin de référence " @@ -12935,6 +13074,9 @@ msgstr "" "[no-]recommend-shallow] [--reference <dépôt>] [--recursive] [--[no-]single-" "branch] [--] [<chemin>...]" +msgid "Failed to resolve HEAD as a valid ref." +msgstr "Échec de résolution de HEAD comme référence valide." + msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<options>] [<chemin>...]" @@ -13413,6 +13555,9 @@ msgstr "(pour porcelaines) oublier les conflits sauvés et non résolus" msgid "write index in this format" msgstr "écrire l'index dans ce format" +msgid "report on-disk index format version" +msgstr "afficher la version du format d'index sur disque" + msgid "enable or disable split index" msgstr "activer ou désactiver l'index scindé" @@ -13438,6 +13583,14 @@ msgstr "marquer les fichiers comme valides pour fsmonitor" msgid "clear fsmonitor valid bit" msgstr "effacer le bit de validité fsmonitor" +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "index-version : précédemment %d, mis à %d" + msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -13596,28 +13749,28 @@ msgstr "Aucune branche source possible, activation de '--orphan'" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan -b %s %s\n" msgstr "" "Si vous vouliez créer un arbre-de-travail contenant une nouvelle branche\n" -"orpheline (une branche sans commit) pour ce dépôt, vous pouvez le faire\n" +"non-née (une branche sans commit) pour ce dépôt, vous pouvez le faire\n" "en utilisant le drapeau --orphan :\n" "\n" " git worktree add --orphan -b %s %s\n" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan %s\n" msgstr "" "Si vous vouliez créer un arbre-de-travail contenant une nouvelle branche\n" -"orpheline (une branche sans commit) pour ce dépôt, vous pouvez le faire\n" +"non-née (une branche sans commit) pour ce dépôt, vous pouvez le faire\n" "en utilisant le drapeau --orphan :\n" "\n" " git worktree add --orphan %s\n" @@ -13680,6 +13833,10 @@ msgid "initializing" msgstr "initialisation" #, c-format +msgid "could not find created worktree '%s'" +msgstr "impossible de trouver l'arbre-de-travail créé '%s'" + +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "Préparation de l'arbre de travail (nouvelle branche '%s')" @@ -13713,15 +13870,12 @@ msgstr "" msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" "Aucune réf locale ou distant n'existe malgré la présence d'au moins un " "distant,\n" -"on arrête ; utilisez 'add -f' pour passe outre ou récupérer le distant avant" - -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "'%s' et '%s' ne peuvent pas être utilisées ensemble" +"on arrête ; utilisez 'add -f' pour passe outre ou récupérer le distant en " +"premier" msgid "checkout <branch> even if already checked out in other worktree" msgstr "" @@ -13734,8 +13888,8 @@ msgstr "créer une nouvelle branche" msgid "create or reset a branch" msgstr "créer ou réinitialiser une branche" -msgid "create unborn/orphaned branch" -msgstr "créer une branche non née/orpheline" +msgid "create unborn branch" +msgstr "créer une branche non née" msgid "populate the new working tree" msgstr "remplissage de la nouvelle copie de travail" @@ -13757,11 +13911,9 @@ msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "les options '%s', '%s' et '%s' ne peuvent pas être utilisées ensemble" #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "les options '%s' et '%s' ne peuvent pas être utilisées ensemble" - -msgid "<commit-ish>" -msgstr "<commit-esque>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "" +"l'option '%s' et des commit-esques ne peuvent pas être utilisés ensemble" msgid "added with --lock" msgstr "ajouté avec --lock" @@ -14043,16 +14195,20 @@ msgid "terminating chunk id appears earlier than expected" msgstr "l'identifiant de terminaison de tronçon apparaît plus tôt qu'attendu" #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "id de tronçon %<PRIx32> non alignés sur %d octets" + +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" -msgstr "décalage(s) de section incorrect(s) %<PRIx64> et %<PRIx64>" +msgstr "décalage(s) de tronçon incorrect(s) %<PRIx64> et %<PRIx64>" #, c-format msgid "duplicate chunk ID %<PRIx32> found" -msgstr "ID de section dupliqué %<PRIx32>" +msgstr "ID de tronçon dupliqué %<PRIx32>" #, c-format msgid "final chunk has non-zero id %<PRIx32>" -msgstr "la section finale a un id non nul %<PRIx32>" +msgstr "le tronçon final a un id non nul %<PRIx32>" msgid "invalid hash version" msgstr "version d'empreinte invalide" @@ -14097,10 +14253,8 @@ msgstr "" msgid "Move objects and refs by archive" msgstr "Déplacer les objets et références par archive" -msgid "Provide content or type and size information for repository objects" -msgstr "" -"Fournir le contenu ou l'information de type et taille pour les objets du " -"dépôt" +msgid "Provide contents or details of repository objects" +msgstr "Fournir le contenu ou les détails des objets du dépôt" msgid "Display gitattributes information" msgstr "Afficher les informations gitattributes" @@ -14400,6 +14554,11 @@ msgstr "Empaqueter les objets non-empaquetés d'un dépôt" msgid "Create, list, delete refs to replace objects" msgstr "Créer, lister, supprimer des référence pour remplacer des objets" +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "" +"EXPÉRIMENTAL ; rejoue des commits sur une nouvelle base, fonctionne aussi " +"avec les dépôts nus" + msgid "Generates a summary of pending changes" msgstr "Générer une résumé des modifications en attentes" @@ -14524,7 +14683,7 @@ msgstr "Vérifier la signature GPG d'étiquettes" msgid "Display version information about Git" msgstr "Afficher l'information de version à propos de Git" -msgid "Show logs with difference each commit introduces" +msgid "Show logs with differences each commit introduces" msgstr "Afficher les journaux avec la différence que chaque commit introduit" msgid "Manage multiple working trees" @@ -14561,7 +14720,7 @@ msgid "The bundle file format" msgstr "le format du fichier de colis" msgid "Chunk-based file formats" -msgstr "format de fichier avec des sections" +msgstr "format de fichier avec des tronçons" msgid "Git commit-graph format" msgstr "format de graphe de commit de Git" @@ -14642,6 +14801,35 @@ msgstr "Un outil pour gérer les grands dépôts Git" msgid "commit-graph file is too small" msgstr "le graphe de commit est trop petit" +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "" +"le tronçon de distribution d'oid du graphe de commit n'a pas la bonne taille" + +msgid "commit-graph fanout values out of order" +msgstr "les valeurs de distribution du graphe de commit sont désordonnées" + +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "" +"le tronçon de recherche de l'OID du graphe de commits n'a pas la bonne taille" + +msgid "commit-graph commit data chunk is wrong size" +msgstr "le tronçon de données du graphe de commit n'a pas la bonne taille" + +msgid "commit-graph generations chunk is wrong size" +msgstr "le tronçon des générations du graphe de commit n'a pas la bonne taille" + +msgid "commit-graph changed-path index chunk is too small" +msgstr "" +"le tronçon d'index des chemins modifiés du graphe de commit est trop petit" + +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "" +"tronçon de chemin modifié dans le fichier de graphe de commits trop petit " +"((%<PRIuMAX> < %<PRIuMAX>)) ignoré" + #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "" @@ -14659,10 +14847,28 @@ msgstr "" #, c-format msgid "commit-graph file is too small to hold %u chunks" -msgstr "le graphe de commit est trop petit pour contenir %u sections" +msgstr "le graphe de commit est trop petit pour contenir %u tronçons" + +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "" +"le tronçon de distribution des OID requis du graphe de commits est manquant " +"ou corrompu" + +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "" +"le tronçon de recherche OID requis par le graphe de commits est manquant ou " +"corrompu" + +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "" +"le tronçon d'étalement OID requis par le graphe de commits est manquant ou " +"corrompu" msgid "commit-graph has no base graphs chunk" -msgstr "le graphe de commit n'a pas de section de graphes de base" +msgstr "le graphe de commit n'a pas de tronçon de graphes de base" + +msgid "commit-graph base graphs chunk is too small" +msgstr "le tronçon de graphes de base du graphe de commit est trop petit" msgid "commit-graph chain does not match" msgstr "la chaîne de graphe de commit ne correspond pas" @@ -14671,6 +14877,9 @@ msgstr "la chaîne de graphe de commit ne correspond pas" msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "nombre de commits dans le graphe de base trop haut : %<PRIuMAX>" +msgid "commit-graph chain file too small" +msgstr "la chaine du graphe de commit est trop petite" + #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" msgstr "" @@ -14693,6 +14902,14 @@ msgstr "" "le graphe de commits requiert des données de génération de débordement mais " "n'en contient pas" +msgid "commit-graph overflow generation data is too small" +msgstr "" +"les données de génération de débordement du graphe de commits sont trop " +"petites" + +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "pointeur hors-gamme d'arêtes supplémentaires du graphe de commits" + msgid "Loading known commits in commit graph" msgstr "Lecture des commits connus dans un graphe de commit" @@ -14830,20 +15047,6 @@ msgstr "" "la liste de parents du graphe de commit pour le commit %s se termine trop tôt" #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" -"le graphe de commit a un numéro de génération nul pour le commit %s, mais " -"non-nul ailleurs" - -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" -"le graphe de commit a un numéro de génération non-nul pour le commit %s, " -"mais nul ailleurs" - -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "" "la génération du graphe de commit pour le commit %s est %<PRIuMAX> < " @@ -14855,6 +15058,14 @@ msgstr "" "la date de validation pour le commit %s dans le graphe de commit est " "%<PRIuMAX> != %<PRIuMAX>" +#, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "" +"le graphe de commit a des numéros de génération à la fois nuls et non-nuls " +"(par ex. les commits %s et %s)" + msgid "Verifying commits in commit graph" msgstr "Verification des commits dans le graphe de commits" @@ -14882,6 +15093,12 @@ msgstr "" "\"git config advice.graftFileDeprecated false\"" #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "" +"le commit '%s' existe dans la graphe de commit mais pas dans la base de " +"données d'objets" + +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "La validation %s a une signature GPG non fiable, prétendument par %s." @@ -15328,10 +15545,6 @@ msgstr "la référence '%s' ne pointe pas sur un blob" msgid "unable to resolve config blob '%s'" msgstr "impossible de résoudre le blob de config '%s'" -#, c-format -msgid "failed to parse %s" -msgstr "échec de l'analyse de %s" - msgid "unable to parse command-line config" msgstr "lecture de la configuration de ligne de commande impossible" @@ -15814,9 +16027,6 @@ msgstr "impossible d'écrire l'archive" msgid "--merge-base does not work with ranges" msgstr "--merge-base ne fonctionne pas avec des plages" -msgid "--merge-base only works with commits" -msgstr "--merge-base ne fonctionne qu'avec des commits" - msgid "unable to get HEAD" msgstr "impossible d'acquérir HEAD" @@ -15880,6 +16090,10 @@ msgstr "" "Valeur inconnue pour la variable de configuration 'diff.submodule' : '%s'" #, c-format +msgid "unknown value for config '%s': %s" +msgstr "valeur inconnue pour la config '%s' : %s" + +#, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" @@ -15961,13 +16175,6 @@ msgstr "mauvais argument --color-moved : %s" msgid "invalid mode '%s' in --color-moved-ws" msgstr "mode invalide '%s' dans --color-moved-ws" -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"l'option diff-algorithm accept \"myers\", \"minimal\", \"patience\" et " -"\"histogram\"" - #, c-format msgid "invalid argument to %s" msgstr "argument invalide pour %s" @@ -16011,8 +16218,8 @@ msgstr "--stat pour traitement automatique" msgid "output only the last line of --stat" msgstr "afficher seulement la dernière ligne de --stat" -msgid "<param1,param2>..." -msgstr "<param1,param2>..." +msgid "<param1>,<param2>..." +msgstr "<param1>,<param2>..." msgid "" "output the distribution of relative amount of changes for each sub-directory" @@ -16023,8 +16230,8 @@ msgstr "" msgid "synonym for --dirstat=cumulative" msgstr "synonyme pour --dirstat=cumulative" -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "synonyme pour --dirstat=files,param1,param2..." +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "synonyme pour --dirstat=files,<param1>,<param2>..." msgid "warn if changes introduce conflict markers or whitespace errors" msgstr "" @@ -16212,12 +16419,6 @@ msgid "generate diff using the \"histogram diff\" algorithm" msgstr "" "générer un diff en utilisant l'algorithme de différence \"histogramme\"" -msgid "<algorithm>" -msgstr "<algorithme>" - -msgid "choose a diff algorithm" -msgstr "choisir un algorithme de différence" - msgid "<text>" msgstr "<texte>" @@ -17280,12 +17481,12 @@ msgstr "" "existent :\n" "%s" -msgid "Failed to execute internal merge" -msgstr "Échec à l'exécution de la fusion interne" +msgid "failed to execute internal merge" +msgstr "échec à l'exécution de la fusion interne" #, c-format -msgid "Unable to add %s to database" -msgstr "Impossible d'ajouter %s à la base de données" +msgid "unable to add %s to database" +msgstr "impossible d'ajouter %s à la base de données" #, c-format msgid "Auto-merging %s" @@ -17728,6 +17929,21 @@ msgid "multi-pack-index OID fanout is of the wrong size" msgstr "l'étalement de l'OID d'index multi-paquet n'a pas la bonne taille" #, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"étalement oid en désordre : étalement[%d] = %<PRIx32> > %<PRIx32> = " +"étalement[%d]" + +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "" +"le tronçon de recherche de l'OID d'index multi-paquet n'a pas la bonne taille" + +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "" +"le tronçon de décalage de l'OID d'index multi-paquet n'a pas la bonne taille" + +#, c-format msgid "multi-pack-index file %s is too small" msgstr "le fichier d'index multi-paquet %s est trop petit" @@ -17747,17 +17963,28 @@ msgstr "" "la version d'empreinte d'index multi-paquet %u ne correspond pas à la " "version %u" -msgid "multi-pack-index missing required pack-name chunk" -msgstr "index multi-paquet manque de tronçon de nom de paquet" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "" +"le tronçon de nom de paquet requis par l'index multi-paquet est manquant ou " +"corrompu" + +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "" +"le tronçon d'étalement OID requis de l'index multi-paquet est manquant ou " +"corrompu" -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "index multi-paquet manque de tronçon de d'étalement OID requis" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "" +"le tronçon de recherche OID requis de l'index multi-paquet est manquant ou " +"corrompu" -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "index multi-paquet manque de tronçon de recherche OID requis" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "" +"le tronçon de décalage d'objet requis de l'index multi-paquet est manquant " +"ou corrompu" -msgid "multi-pack-index missing required object offsets chunk" -msgstr "index multi-paquet manque de tronçon de décalage d'objet requis" +msgid "multi-pack-index pack-name chunk is too short" +msgstr "le tronçon de nom de paquet de l'index multi-paquet est trop petit" #, c-format msgid "multi-pack-index pack names out of order: '%s' before '%s'" @@ -17768,9 +17995,19 @@ msgstr "" msgid "bad pack-int-id: %u (%u total packs)" msgstr "mauvais pack-int-id : %u (%u paquets au total)" +msgid "MIDX does not contain the BTMP chunk" +msgstr "le MIDX ne contient pas de tronçon BTMP" + +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "impossible d'ouvrir le paquet bitmappé %<PRIu32>" + msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "" -"l'index multi-paquet stock un décalage en 64-bit, mais off_t est trop petit" +"l'index multi-paquet stocke un décalage en 64-bit, mais off_t est trop petit" + +msgid "multi-pack-index large offset out of bounds" +msgstr "le grand décalage de l'index-multi-paquet est hors limite" #, c-format msgid "failed to add packfile '%s'" @@ -17850,13 +18087,6 @@ msgstr "somme de contrôle incorrecte" msgid "Looking for referenced packfiles" msgstr "Recherche de fichiers paquets référencés" -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "" -"étalement oid en désordre : étalement[%d] = %<PRIx32> > %<PRIx32> = " -"étalement[%d]" - msgid "the midx contains no oid" msgstr "le midx ne contient aucun oid" @@ -18383,6 +18613,9 @@ msgstr "l'index inverse requis manque dans l'index multi-paquet" msgid "could not open pack %s" msgstr "impossible d'ouvrir le paquet '%s'" +msgid "could not determine MIDX preferred pack" +msgstr "impossible de déterminer le paquet préféré de MIDX" + #, c-format msgid "preferred pack (%s) is invalid" msgstr "le paquet préféré (%s) est invalide" @@ -18405,6 +18638,10 @@ msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\"" msgstr "bitmap ewah corrompue : entête tronqué pour la bitmap du commit '%s'" #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "impossible de charger le paquet : '%s', pack-reuse désactivé" + +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "objet '%s' non trouvé dans les bitmaps de type" @@ -18492,6 +18729,13 @@ msgstr "somme de contrôle invalide" msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "position de rev-index invalide à %<PRIu64> : %<PRIu32> != %<PRIu32>" +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "" +"le tronçon d'index inversé de l'index multi-paquet n'a pas la bonne taille" + +msgid "could not determine preferred pack" +msgstr "impossible de déterminer le paquet préféré" + msgid "cannot both write and verify reverse index" msgstr "impossible de lire et vérifier à la fois l'index inverse" @@ -18544,14 +18788,6 @@ msgid "%s requires a value" msgstr "%s a besoin d'une valeur" #, c-format -msgid "%s is incompatible with %s" -msgstr "%s est incompatible avec %s" - -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s est incompatible avec toute autre option" - -#, c-format msgid "%s takes no value" msgstr "%s n'accepte aucune valeur" @@ -18634,6 +18870,10 @@ msgstr " %s" msgid "-NUM" msgstr "-NUM" +#, c-format +msgid "opposite of --no-%s" +msgstr "opposé de --no-%s" + msgid "expiry-date" msgstr "date-d'expiration" @@ -18665,6 +18905,14 @@ msgstr "" "caractère NUL" #, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "valeur booléenne d'environnement invalide '%s' pour '%s'" + +#, c-format +msgid "failed to parse %s" +msgstr "échec de l'analyse de %s" + +#, c-format msgid "Could not make %s writable by group" msgstr "Impossible de rendre %s inscriptible pour le groupe" @@ -18715,6 +18963,10 @@ msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s : 'literal' et 'glob' sont incompatibles" #, c-format +msgid "'%s' is outside the directory tree" +msgstr "'%s' est hors de l'arbre de répertoire" + +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s : '%s' est hors du dépôt à '%s'" @@ -18876,10 +19128,6 @@ msgid "unable to add '%s' to index" msgstr "impossible d'ajouter '%s' à l'index" #, c-format -msgid "unable to stat '%s'" -msgstr "fstat de '%s' impossible" - -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "'%s' existe à la fois comme un fichier et un répertoire" @@ -18987,10 +19235,6 @@ msgid "failed to convert to a sparse-index" msgstr "échec de conversion d'un index clairsemé" #, c-format -msgid "could not stat '%s'" -msgstr "impossible de stat '%s'" - -#, c-format msgid "unable to open git dir: %s" msgstr "impossible d'ouvrir le répertoire git : %s" @@ -19460,10 +19704,6 @@ msgid "cannot process '%s' and '%s' at the same time" msgstr "impossible de traiter '%s' et '%s' en même temps" #, c-format -msgid "could not remove reference %s" -msgstr "impossible de supprimer la référence %s" - -#, c-format msgid "could not delete reference %s: %s" msgstr "impossible de supprimer la référence %s : %s" @@ -19658,7 +19898,7 @@ msgid "" "Neither worked, so we gave up. You must fully qualify the ref." msgstr "" "La destination que vous avez fournie n'est pas un nom de référence complète\n" -"(c'est-à -dire commençant par \"ref/\"). Essai d'approximation par :\n" +"(c'est-à -dire commençant par \"refs/\"). Essai d'approximation par :\n" "\n" "- Recherche d'une référence qui correspond à '%s' sur le serveur distant.\n" "- Vérification si la <source> en cours de poussée ('%s')\n" @@ -20032,8 +20272,16 @@ msgstr "lors d'un clonage, créer un répertoire de travail complet" msgid "only download metadata for the branch that will be checked out" msgstr "ne télécharger les méta-données que pour la branche qui sera extraite" -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [<options>] [--] <dépôt> [<répertoire>]" +msgid "create repository within 'src' directory" +msgstr "Créer un dépôt dans le repertoire 'src'" + +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <branche-principale>] [--full-" +"clone]\n" +"\t[--[no-]src] <url> [<enrôlement>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20084,12 +20332,28 @@ msgid "could not remove stale scalar.repo '%s'" msgstr "impossible de supprimé le scalar.repo obsolète '%s'" #, c-format -msgid "removing stale scalar.repo '%s'" +msgid "removed stale scalar.repo '%s'" msgstr "suppression du scalar.repo obsolète '%s'" #, c-format -msgid "git repository gone in '%s'" -msgstr "dépôt git parti dans '%s'" +msgid "repository at '%s' has different owner" +msgstr "le dépôt dans '%s' a un propriétaire différent" + +#, c-format +msgid "repository at '%s' has a format issue" +msgstr "le dépôt dans '%s' a un problème de format" + +#, c-format +msgid "repository not found in '%s'" +msgstr "dépôt non trouvé dans '%s'" + +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"pour désinscrire ce dépôt de Scalar, lancez\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" msgid "" "scalar run <task> [<enlistment>]\n" @@ -20497,10 +20761,6 @@ msgid "%s: cannot parse parent commit %s" msgstr "%s : impossible d'analyser le commit parent %s" #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "impossible de renommer '%s' en '%s'" - -#, c-format msgid "could not revert %s... %s" msgstr "impossible d'annuler %s... %s" @@ -20826,6 +21086,9 @@ msgid "Autostash exists; creating a new stash entry." msgstr "" "Un remisage automatique existe ; création d'une nouvelle entrée de remisage." +msgid "autostash reference is a symref" +msgstr "la référence d'auto-remisage est une symref" + msgid "could not detach HEAD" msgstr "impossible de détacher HEAD" @@ -20858,14 +21121,14 @@ msgstr "" " git rebase --continue\n" #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "Rebasage (%d/%d)%s" - -#, c-format msgid "Stopped at %s... %.*s\n" msgstr "Arrêt à %s... %.*s\n" #, c-format +msgid "Rebasing (%d/%d)%s" +msgstr "Rebasage (%d/%d)%s" + +#, c-format msgid "unknown command %d" msgstr "commande inconnue %d" @@ -21145,6 +21408,10 @@ msgid "invalid initial branch name: '%s'" msgstr "nom de branche initiale invalide : '%s'" #, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "re-initialisation : --initial-branch=%s ignoré" + +#, c-format msgid "unable to handle file type %d" msgstr "impossible de traiter le fichier de type %d" @@ -21155,15 +21422,17 @@ msgstr "impossible de déplacer %s vers %s" msgid "attempt to reinitialize repository with different hash" msgstr "essai de réinitialisation du dépôt avec une empreinte différente" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "" +"essai de réinitialisation du dépôt avec un format de stockage de références " +"différent" + #, c-format msgid "%s already exists" msgstr "%s existe déjà " #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "re-initialisation : --initial-branch=%s ignoré" - -#, c-format msgid "Reinitialized existing shared Git repository in %s%s\n" msgstr "Dépôt Git existant partagé réinitialisé dans %s%s\n" @@ -21432,12 +21701,6 @@ msgstr "effacer l'arbre de cache avant chaque itération" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "nombre d'entrées dans l'arbre de cache à invalider (par défaut, 0)" -msgid "unhandled options" -msgstr "options non gérées" - -msgid "error preparing revisions" -msgstr "erreur lors de la préparation des révisions" - #, c-format msgid "commit %s is not marked reachable" msgstr "le commit %s n'est pas marqué joignable" @@ -21597,9 +21860,6 @@ msgstr "" msgid "invalid remote service path" msgstr "chemin de service distant invalide" -msgid "operation not supported by protocol" -msgstr "option non supportée par le protocole" - #, c-format msgid "can't connect to subservice %s" msgstr "impossible de se connecter au sous-service %s" @@ -21732,10 +21992,6 @@ msgid "support for protocol v2 not implemented yet" msgstr "le support du protocole v2 n'est pas encore implanté" #, c-format -msgid "unknown value for config '%s': %s" -msgstr "valeur inconnue pour la config '%s' : %s" - -#, c-format msgid "transport '%s' not allowed" msgstr "transport '%s' non permis" @@ -21789,6 +22045,9 @@ msgid "could not retrieve server-advertised bundle-uri list" msgstr "" "impossible de récupérer la liste de bundle-uris annoncée par le serveur" +msgid "operation not supported by protocol" +msgstr "option non supportée par le protocole" + msgid "too-short tree object" msgstr "objet arbre trop court" @@ -22189,6 +22448,9 @@ msgstr "impossible d'accéder à '%s'" msgid "unable to get current working directory" msgstr "impossible d'accéder au répertoire de travail courant" +msgid "unable to get random bytes" +msgstr "impossible d'acquérir des octets aléatoires" + msgid "Unmerged paths:" msgstr "Chemins non fusionnés :" @@ -22635,6 +22897,10 @@ msgstr "de plus, votre index contient des modifications non validées." msgid "cannot %s: Your index contains uncommitted changes." msgstr "%s impossible : votre index contient des modifications non validées." +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "style inconnu '%s' pour '%s'" + msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" @@ -22828,13 +23094,13 @@ msgstr "" "Effacez le corps si vous ne souhaitez pas envoyer un résumé.\n" #, perl-format -msgid "Failed to open %s: %s" -msgstr "Échec à l'ouverture de %s : %s" - -#, perl-format msgid "Failed to open %s.final: %s" msgstr "Échec à l'ouverture de %s.final : %s" +#, perl-format +msgid "Failed to open %s: %s" +msgstr "Échec à l'ouverture de %s : %s" + msgid "Summary email is empty, skipping it\n" msgstr "Le courriel de résumé étant vide, il a été ignoré\n" @@ -23036,6 +23302,123 @@ msgstr "%s sauté avec un suffix de sauvegarde '%s'.\n" msgid "Do you really want to send %s? [y|N]: " msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : " +#~ msgid "-x and -X cannot be used together" +#~ msgstr "-x et -X ne peuvent pas être utilisés ensemble" + +#~ msgid "" +#~ "--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" +#~ "exclude" +#~ msgstr "" +#~ "--bundle-uri est incompatible avec --depth, --shallow-since, et --shallow-" +#~ "exclude" + +#~ msgid "--merge-base is incompatible with --stdin" +#~ msgstr "--merge-base est incompatible avec --stdin" + +#~ msgid "" +#~ "apply options are incompatible with rebase.autoSquash. Consider adding --" +#~ "no-autosquash" +#~ msgstr "" +#~ "les options d'application sont incompatibles avec rebase.autoSquash. " +#~ "Considérez l'ajout de --no-autosquash" + +#~ msgid "--exclude-hidden cannot be used together with --branches" +#~ msgstr "--exclude-hidden ne peut être utilisé avec --branches" + +#~ msgid "--exclude-hidden cannot be used together with --tags" +#~ msgstr "--exclude-hidden ne peut pas être utilisé avec --tags" + +#~ msgid "--exclude-hidden cannot be used together with --remotes" +#~ msgstr "--exclude-hidden ne peut pas être utilisé avec --remotes" + +#, c-format +#~ msgid "only one of '%s', '%s' or '%s' can be given" +#~ msgstr "les options '%s', '%s' et '%s' sont mutuellement exclusives" + +#, c-format +#~ msgid "'%s' and '%s' cannot be used together" +#~ msgstr "'%s' et '%s' ne peuvent pas être utilisées ensemble" + +#, c-format +#~ msgid "options '%s', and '%s' cannot be used together" +#~ msgstr "les options '%s' et '%s' ne peuvent pas être utilisées ensemble" + +#~ msgid "<commit-ish>" +#~ msgstr "<commit-esque>" + +#, c-format +#~ msgid "%s is incompatible with %s" +#~ msgstr "%s est incompatible avec %s" + +#, c-format +#~ msgid "could not remove reference %s" +#~ msgstr "impossible de supprimer la référence %s" + +#~ msgid "unhandled options" +#~ msgstr "options non gérées" + +#, c-format +#~ msgid "options '%s=%s' and '%s=%s' cannot be used together" +#~ msgstr "" +#~ "les options '%s=%s' et '%s=%s' ne peuvent pas être utilisées ensemble" + +#, c-format +#~ msgid "%s : incompatible with something else" +#~ msgstr "%s est incompatible avec toute autre option" + +#~ msgid "Could not write patch" +#~ msgstr "Impossible d'écrire le patch" + +#, c-format +#~ msgid "Could not stat '%s'" +#~ msgstr "Stat de '%s' impossible" + +#, c-format +#~ msgid "Cannot delete branch '%s' checked out at '%s'" +#~ msgstr "Impossible de supprimer la branche '%s' extraite dans '%s'" + +#~ msgid "unable to write new_index file" +#~ msgstr "impossible d'écrire le fichier new_index" + +#~ msgid "do not apply config rules" +#~ msgstr "ne pas appliquer les règles de la configuration" + +#~ msgid "join whitespace-continued values" +#~ msgstr "joindre les valeurs continuées avec des caractères blancs" + +#~ msgid "set parsing options" +#~ msgstr "paramètres d'analyse" + +#~ msgid "cannot move directory over file" +#~ msgstr "impossible de déplacer un répertoire sur un fichier" + +#~ msgid "cannot use --filter without --stdout" +#~ msgstr "impossible d'utiliser --filter sans --stdout" + +#~ msgid "cannot use --max-pack-size with --cruft" +#~ msgstr "impossible d'utiliser --max-pack-size avec --cruft" + +#~ msgid "--strategy requires --merge or --interactive" +#~ msgstr "--strategy requiert --merge ou --interactive" + +#, c-format +#~ msgid "" +#~ "commit-graph has generation number zero for commit %s, but non-zero " +#~ "elsewhere" +#~ msgstr "" +#~ "le graphe de commit a un numéro de génération nul pour le commit %s, mais " +#~ "non-nul ailleurs" + +#~ msgid "--merge-base only works with commits" +#~ msgstr "--merge-base ne fonctionne qu'avec des commits" + +#~ msgid "scalar clone [<options>] [--] <repo> [<dir>]" +#~ msgstr "scalar clone [<options>] [--] <dépôt> [<répertoire>]" + +#, c-format +#~ msgid "could not rename '%s' to '%s'" +#~ msgstr "impossible de renommer '%s' en '%s'" + #, c-format #~ msgid "It is not possible to %s because you have unmerged files." #~ msgstr "%s n'est pas possible car vous avez des fichiers non fusionnés." @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-06 17:06+0700\n" -"PO-Revision-Date: 2023-08-06 17:06+0700\n" +"POT-Creation-Date: 2024-02-16 09:36+0700\n" +"PO-Revision-Date: 2024-02-16 10:45+0700\n" "Last-Translator: Bagas Sanjaya <bagasdotme@gmail.com>\n" "Language-Team: Indonesian\n" "Language: id\n" @@ -764,9 +764,8 @@ msgid "Reverting is not possible because you have unmerged files." msgstr "Pembalikkan tidak mungkin sebab Anda punya berkas tak tergabung." #: advice.c -#, c-format -msgid "It is not possible to %s because you have unmerged files." -msgstr "Tidak mungkin untuk %s sebab Anda punya berkas tak tergabung." +msgid "Rebasing is not possible because you have unmerged files." +msgstr "Pendasaran ulang tidak mungkin sebab Anda punya berkas tak tergabung." #: advice.c msgid "" @@ -910,7 +909,7 @@ msgid "unclosed quote" msgstr "tanda kutip tak ditutup" #: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c -#: builtin/receive-pack.c builtin/tag.c +#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c msgid "too many arguments" msgstr "terlalu banyak argumen" @@ -924,14 +923,16 @@ msgstr "opsi spasi putih tidak dikenal '%s'" msgid "unrecognized whitespace ignore option '%s'" msgstr "opsi abai spasi putih tidak dikenal '%s'" -#: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout.c -#: builtin/clone.c builtin/commit.c builtin/describe.c builtin/diff-tree.c -#: builtin/difftool.c builtin/fast-export.c builtin/fetch.c builtin/help.c -#: builtin/index-pack.c builtin/init-db.c builtin/log.c builtin/ls-files.c -#: builtin/merge-base.c builtin/merge.c builtin/pack-objects.c builtin/push.c -#: builtin/rebase.c builtin/repack.c builtin/reset.c builtin/rev-list.c -#: builtin/show-branch.c builtin/stash.c builtin/submodule--helper.c -#: builtin/tag.c builtin/worktree.c parse-options.c range-diff.c revision.c +#: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c +#: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c +#: builtin/describe.c builtin/diff-tree.c builtin/difftool.c +#: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c +#: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c +#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c +#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-list.c +#: builtin/rev-parse.c builtin/show-branch.c builtin/stash.c +#: builtin/submodule--helper.c builtin/tag.c builtin/worktree.c parse-options.c +#: range-diff.c revision.c #, c-format msgid "options '%s' and '%s' cannot be used together" msgstr "Opsi '%s' dan '%s' tidak dapat digunakan bersamaan" @@ -1421,7 +1422,7 @@ msgid_plural "%d lines applied after fixing whitespace errors." msgstr[0] "%d baris diterapkan setelah memperbaiki kesalahan spasi putih." msgstr[1] "%d baris diterapkan setelah memperbaiki kesalahan spasi putih." -#: apply.c builtin/add.c builtin/mv.c builtin/rm.c +#: apply.c builtin/mv.c builtin/rm.c msgid "Unable to write new index file" msgstr "Tidak dapat menulis berkas indeks baru" @@ -1754,6 +1755,11 @@ msgstr "Opsi --output tak diharapkan" #: archive.c #, c-format +msgid "extra command line parameter '%s'" +msgstr "parameter konfigurasi tambahan: '%s'" + +#: archive.c +#, c-format msgid "Unknown archive format '%s'" msgstr "Format arsip tidak dikenal '%s'" @@ -1808,6 +1814,17 @@ msgstr "mengabaikan blob gitattributes '%s' yang terlalu besar" msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "--attr-source atau GIT_ATTR_SOURCE jelek" +#: attr.c read-cache.c +#, c-format +msgid "unable to stat '%s'" +msgstr "tidak dapat men-stat '%s'" + +#: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c +#: builtin/pack-objects.c combine-diff.c rerere.c +#, c-format +msgid "unable to read %s" +msgstr "tidak dapat membaca %s" + #: bisect.c #, c-format msgid "Badly quoted content in file '%s': %s" @@ -2143,8 +2160,8 @@ msgstr "submodul '%s': tidak dapat membuat cabang '%s'" #: branch.c #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "'%s' sudah di-checkout pada '%s'" +msgid "'%s' is already used by worktree at '%s'" +msgstr "'%s' sudah digunakan oleh pohon kerja di '%s'" #: builtin/add.c msgid "git add [<options>] [--] <pathspec>..." @@ -2167,31 +2184,27 @@ msgstr "" "setelan add.interactive.useBuiltin sudah dihapus!\n" "Selengkapnya lihat entrinya di 'git help config'." -#: builtin/add.c builtin/rev-parse.c -msgid "Could not read the index" -msgstr "Tidak dapat membaca indeks" - #: builtin/add.c -msgid "Could not write patch" -msgstr "Tidak dapat menulis tambalan" +msgid "could not read the index" +msgstr "tidak dapat membaca indeks" #: builtin/add.c msgid "editing patch failed" msgstr "Gagal menyunting tambalan" -#: builtin/add.c +#: builtin/add.c read-cache.c #, c-format -msgid "Could not stat '%s'" -msgstr "Tidak dapat men-stat '%s'" +msgid "could not stat '%s'" +msgstr "tidak dapat men-stat '%s'" #: builtin/add.c -msgid "Empty patch. Aborted." -msgstr "Tambalan kosong. Dibatalkan." +msgid "empty patch. aborted" +msgstr "tambalan kosong, dibatalkan" #: builtin/add.c #, c-format -msgid "Could not apply '%s'" -msgstr "Tidak dapat terapkan '%s'" +msgid "could not apply '%s'" +msgstr "tidak dapat menerapkan '%s'" #: builtin/add.c msgid "The following paths are ignored by one of your .gitignore files:\n" @@ -2352,14 +2365,19 @@ msgstr "" msgid "index file corrupt" msgstr "berkas indeks rusak" +#: builtin/add.c builtin/am.c builtin/checkout.c builtin/clone.c +#: builtin/commit.c builtin/stash.c merge.c rerere.c +msgid "unable to write new index file" +msgstr "gagal menulis berkas indeks baru" + #: builtin/am.c builtin/mailinfo.c mailinfo.c #, c-format msgid "bad action '%s' for '%s'" msgstr "tindakan jelek '%s' untuk '%s'" #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c -#: builtin/pull.c diff-merges.c gpg-interface.c ls-refs.c parallel-checkout.c -#: sequencer.c setup.c +#: builtin/pull.c config.c diff-merges.c gpg-interface.c ls-refs.c +#: parallel-checkout.c sequencer.c setup.c #, c-format msgid "invalid value for '%s': '%s'" msgstr "nilai tidak valid untuk '%s': '%s'" @@ -2522,8 +2540,7 @@ msgstr "git write-tree gagal menulis sebuah pohon" msgid "applying to an empty history" msgstr "menerapkan ke sebuah riwayat kosong" -#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c -#: t/helper/test-fast-rebase.c +#: builtin/am.c builtin/commit.c builtin/merge.c builtin/replay.c sequencer.c msgid "failed to write commit object" msgstr "gagal menulis objek komit" @@ -2615,11 +2632,6 @@ msgstr "" "Anda mungkin jalankan `git rm` pada berkas untuk menerima \"penghapusan oleh " "mereka\" untuk itu." -#: builtin/am.c builtin/checkout.c builtin/clone.c builtin/stash.c merge.c -#: rerere.c -msgid "unable to write new index file" -msgstr "gagal menulis berkas indeks baru" - #: builtin/am.c builtin/reset.c #, c-format msgid "Could not parse object '%s'." @@ -2643,11 +2655,6 @@ msgid "failed to read '%s'" msgstr "gagal membaca '%s'" #: builtin/am.c -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "Opsi '%s=%s' dan '%s=%s' tidak dapat digunakan bersamaan" - -#: builtin/am.c msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<opsi>] [(<mbox> | <Maildir>)...]" @@ -2719,8 +2726,9 @@ msgid "n" msgstr "n" #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c -#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c -#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c +#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c +#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c +#: builtin/verify-tag.c msgid "format" msgstr "format" @@ -2851,10 +2859,10 @@ msgstr "git archive: sebuah bilasan diharapkan" #: builtin/bisect.c msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=<istilah> --term-{old, good}=<istilah>] " +"git bisect start [--term-(new,bad)=<istilah> --term-(old, good)=<istilah>] " "[--no-checkout] [--first-parent] [<jelek> [<bagus>...]] [--] [<jalur>...]" #: builtin/bisect.c @@ -2874,8 +2882,8 @@ msgid "git bisect replay <logfile>" msgstr "git bisect replay <berkas log>" #: builtin/bisect.c -msgid "git bisect run <cmd>..." -msgstr "git bisect run <perintah>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <perintah> [<argumen>...]" #: builtin/bisect.c #, c-format @@ -3394,37 +3402,38 @@ msgstr "git branch [<opsi>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" "menghapus cabang '%s' yang sudah digabungkan ke\n" -" '%s', tapi belum digabungkan ke HEAD." +" '%s', tapi belum digabungkan ke HEAD" #: builtin/branch.c #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" "tidak menghapus cabang '%s' yang belum digabungkan ke\n" -" '%s', walaupun tergabung ke HEAD." +" '%s', walaupun tergabung ke HEAD" #: builtin/branch.c #, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "Tidak dapat mencari objek komit untuk '%s'" +msgid "couldn't look up commit object for '%s'" +msgstr "tidak dapat mencari objek komit untuk '%s'" #: builtin/branch.c #, 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 "" -"Cabang '%s' belum sepenuhnya tergabung.\n" -"Kalau Anda yakin ingin menghapusnya, jalankan 'git branch -D %s'." +msgid "the branch '%s' is not fully merged" +msgstr "cabang '%s' belum sepenuhnya digabungkan" + +#: builtin/branch.c +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" +msgstr "Jika anda yakin untuk menghapusnya, lakukan 'git branch -D %s'" #: builtin/branch.c -msgid "Update of config-file failed" -msgstr "Pembaruan berkas konfigurasi gagal" +msgid "update of config-file failed" +msgstr "pembaruan berkas konfigurasi gagal" #: builtin/branch.c msgid "cannot use -a with -d" @@ -3432,13 +3441,14 @@ msgstr "tidak dapat gunakan -a dengan -d" #: builtin/branch.c #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "Tidak dapat menghapus cabang '%s' yang ter-checkout pada '%s'" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "" +"tidak dapat menghapus cabang '%s' yang digunakan oleh pohon kerja di '%s'" #: builtin/branch.c #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "cabang pelacak remote '%s' tidak ditemukan." +msgid "remote-tracking branch '%s' not found" +msgstr "cabang pelacak remote '%s' tidak ditemukan" #: builtin/branch.c #, c-format @@ -3451,8 +3461,8 @@ msgstr "" #: builtin/branch.c #, c-format -msgid "branch '%s' not found." -msgstr "cabang '%s' tidak ditemukan." +msgid "branch '%s' not found" +msgstr "cabang '%s' tidak ditemukan" #: builtin/branch.c #, c-format @@ -3479,13 +3489,13 @@ msgstr "HEAD (%s) merujuk diluar refs/heads/" #: builtin/branch.c #, c-format -msgid "Branch %s is being rebased at %s" -msgstr "Cabang %s sedang didasarkan ulang pada %s" +msgid "branch %s is being rebased at %s" +msgstr "cabang %s sedang didasarkan ulang pada %s" #: builtin/branch.c #, c-format -msgid "Branch %s is being bisected at %s" -msgstr "Cabang %s sedang dibagi dua pada %s" +msgid "branch %s is being bisected at %s" +msgstr "cabang %s sedang dibagi dua pada %s" #: builtin/branch.c #, c-format @@ -3494,49 +3504,49 @@ msgstr "HEAD dari pohon kerja %s tidak diperbarui" #: builtin/branch.c #, c-format -msgid "Invalid branch name: '%s'" -msgstr "Nama cabang tidak valid: '%s'" +msgid "invalid branch name: '%s'" +msgstr "nama cabang tidak valid: '%s'" #: builtin/branch.c #, c-format -msgid "No commit on branch '%s' yet." -msgstr "Belum ada komit pada cabang '%s'." +msgid "no commit on branch '%s' yet" +msgstr "belum ada komit pada cabang '%s'." #: builtin/branch.c #, c-format -msgid "No branch named '%s'." -msgstr "Tidak ada cabang bernama '%s'." +msgid "no branch named '%s'" +msgstr "tidak ada cabang bernama '%s'" #: builtin/branch.c -msgid "Branch rename failed" -msgstr "Penggantian nama cabang gagal" +msgid "branch rename failed" +msgstr "penggantian nama cabang gagal" #: builtin/branch.c -msgid "Branch copy failed" -msgstr "Penyalinan cabang gagal" +msgid "branch copy failed" +msgstr "penyalinan cabang gagal" #: builtin/branch.c #, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "Salinan cabang salah nama '%s' dibuat" +msgid "created a copy of a misnamed branch '%s'" +msgstr "salinan cabang salah nama '%s' dibuat" #: builtin/branch.c #, c-format -msgid "Renamed a misnamed branch '%s' away" -msgstr "Cabang salah nama '%s' berganti nama" +msgid "renamed a misnamed branch '%s' away" +msgstr "cabang salah nama '%s' berganti nama" #: builtin/branch.c #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "Cabang berganti nama ke %s, tapi HEAD tidak diperbarui!" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "cabang berganti nama ke %s, tapi HEAD tidak diperbarui" #: builtin/branch.c -msgid "Branch is renamed, but update of config-file failed" -msgstr "Cabang berganti nama, tapi pembaruan berkas konfigurasi gagal" +msgid "branch is renamed, but update of config-file failed" +msgstr "cabang berganti nama, tapi pembaruan berkas konfigurasi gagal" #: builtin/branch.c -msgid "Branch is copied, but update of config-file failed" -msgstr "Cabang disalin, tapi pembaruan berkas konfigurasi gagal" +msgid "branch is copied, but update of config-file failed" +msgstr "cabang disalin, tapi pembaruan berkas konfigurasi gagal" #: builtin/branch.c #, c-format @@ -3686,9 +3696,9 @@ msgstr "rekursi melalui submodul" msgid "format to use for the output" msgstr "format yang digunakan untuk keluaran" -#: builtin/branch.c builtin/submodule--helper.c submodule.c -msgid "Failed to resolve HEAD as a valid ref." -msgstr "Gagal menguraikan HEAD sebagai referensi valid." +#: builtin/branch.c +msgid "failed to resolve HEAD as a valid ref" +msgstr "gagal menguraikan HEAD sebagai referensi valid." #: builtin/branch.c builtin/clone.c msgid "HEAD not found below refs/heads!" @@ -3711,20 +3721,20 @@ msgid "branch name required" msgstr "nama cabang diperlukan" #: builtin/branch.c -msgid "Cannot give description to detached HEAD" -msgstr "Tidak dapat memberikan deskripsi ke HEAD terpisah" +msgid "cannot give description to detached HEAD" +msgstr "tidak dapat memberikan deskripsi ke HEAD terpisah" #: builtin/branch.c msgid "cannot edit description of more than one branch" msgstr "tidak dapat menyunting deskripsi lebih dari satu cabang" #: builtin/branch.c -msgid "cannot copy the current branch while not on any." -msgstr "tidak dapat menyalin cabang saat ini ketika tidak ada." +msgid "cannot copy the current branch while not on any" +msgstr "tidak dapat menyalin cabang saat ini ketika tidak ada" #: builtin/branch.c -msgid "cannot rename the current branch while not on any." -msgstr "tidak dapat mengganti nama cabang saat ini ketika tidak ada." +msgid "cannot rename the current branch while not on any" +msgstr "tidak dapat mengganti nama cabang saat ini ketika tidak ada" #: builtin/branch.c msgid "too many branches for a copy operation" @@ -3741,10 +3751,9 @@ msgstr "terlalu banyak argumen untuk menyetel hulu baru" #: builtin/branch.c #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." +"could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" -"tidak dapat menyetel hulu HEAD ke %s ketika itu tak menunjuk pada cabang " -"apapun." +"tidak dapat menyetel hulu HEAD ke %s ketika tak menunjuk pada cabang apapun" #: builtin/branch.c #, c-format @@ -3761,31 +3770,30 @@ msgid "too many arguments to unset upstream" msgstr "terlalu banyak argumen untuk batal-setel hulu" #: builtin/branch.c -msgid "could not unset upstream of HEAD when it does not point to any branch." +msgid "could not unset upstream of HEAD when it does not point to any branch" msgstr "" -"tidak dapat membatal-setel hulu HEAD ketika itu tak menunjuk pada cabang " -"apapun." +"tidak dapat membatal-setel hulu HEAD ketika tak menunjuk pada cabang apapun" #: builtin/branch.c #, c-format -msgid "Branch '%s' has no upstream information" -msgstr "Cabang '%s' tidak ada informasi hulu" +msgid "branch '%s' has no upstream information" +msgstr "cabang '%s' tidak ada informasi hulu" #: builtin/branch.c msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"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 "" -"Opsi -a dan -r tidak mengambil nama cabang.\n" -"Mungkin maksud Anda gunakan: -a|-r --list <pola>?" +"opsi -a dan -r tidak mengambil nama cabang.\n" +"Mungkin maksud Anda menggunakan: -a|-r --list <pola>?" #: builtin/branch.c msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." +"'--set-upstream-to' instead" msgstr "" "opsi '--set-upstream' tidak lagi didukung. Mohon gunakan '--track' atau '--" -"set-upstream-to' sebagai gantinya." +"set-upstream-to' sebagai gantinya" #: builtin/bugreport.c msgid "git version:\n" @@ -3871,6 +3879,11 @@ msgstr "sebutkan tujuan untuk berkas(-berkas) laporan bug" msgid "specify a strftime format suffix for the filename(s)" msgstr "sebutkan akhiran format strftime untuk nama(-nama) berkas" +#: builtin/bugreport.c +#, c-format +msgid "unknown argument `%s'" +msgstr "argumen tidak dikenal `%s'" + #: builtin/bugreport.c builtin/diagnose.c #, c-format msgid "could not create leading directories for '%s'" @@ -4010,6 +4023,15 @@ msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objek>" #: builtin/cat-file.c msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<revisi>:<jalur|mirip-pohon> | --path=<jalur|mirip-pohon>] " +"<revisi>" + +#: builtin/cat-file.c +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -4021,15 +4043,6 @@ msgstr "" " [--textconv | --filters] [-z]" #: builtin/cat-file.c -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<revisi>:<jalur|mirip-pohon> | --path=<jalur|mirip-pohon>] " -"<revisi>" - -#: builtin/cat-file.c msgid "Check object existence or emit object contents" msgstr "Periksa keberadaan objek atau keluarkan isi objek" @@ -4417,6 +4430,11 @@ msgstr "'%s' atau '%s' tidak dapat digunakan untuk %s" #: builtin/checkout.c #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "'%s', '%s', atau '%s' tidak dapat digunakan ketika men-checkout pohon" + +#: builtin/checkout.c +#, c-format msgid "path '%s' is unmerged" msgstr "jalur '%s' tak tergabung" @@ -4443,7 +4461,7 @@ msgstr "Tidak dapat melakukan reflog untuk '%s': %s\n" msgid "HEAD is now at" msgstr "HEAD sekarang berada di" -#: builtin/checkout.c builtin/clone.c t/helper/test-fast-rebase.c +#: builtin/checkout.c builtin/clone.c msgid "unable to update HEAD" msgstr "tidak dapat memperbarui HEAD" @@ -4714,8 +4732,8 @@ msgid "new-branch" msgstr "cabang baru" #: builtin/checkout.c -msgid "new unparented branch" -msgstr "cabang baru tanpa induk" +msgid "new unborn branch" +msgstr "cabang yatim baru" #: builtin/checkout.c builtin/merge.c msgid "update ignored files (default)" @@ -4783,7 +4801,7 @@ msgstr "" msgid "you must specify path(s) to restore" msgstr "Anda harus sebutkan jalur untuk dipulihkan" -#: builtin/checkout.c builtin/clone.c builtin/remote.c +#: builtin/checkout.c builtin/clone.c builtin/remote.c builtin/replay.c #: builtin/submodule--helper.c builtin/worktree.c msgid "branch" msgstr "cabang" @@ -5027,10 +5045,6 @@ msgstr "" "clean.requireForce asal ke true dan baik -i, -n, atau -f tidak diberikan; " "menolak membersihkan" -#: builtin/clean.c -msgid "-x and -X cannot be used together" -msgstr "-x dan -X tidak dapat digunakan bersamaan" - #: builtin/clone.c msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<opsi>] [--] <repo> [<direktori>]" @@ -5109,7 +5123,7 @@ msgstr "checkout <cabang> daripada HEAD remote" msgid "path to git-upload-pack on the remote" msgstr "jalur ke git-upload-pack pada remote" -#: builtin/clone.c builtin/fetch.c builtin/grep.c builtin/pull.c +#: builtin/clone.c builtin/fetch.c builtin/pull.c msgid "depth" msgstr "kedalaman" @@ -5122,6 +5136,7 @@ msgid "create a shallow clone since a specific time" msgstr "buat klon dangkal sejak waktu yang disebutkan" #: builtin/clone.c builtin/fetch.c builtin/pull.c builtin/rebase.c +#: builtin/replay.c msgid "revision" msgstr "revisi" @@ -5149,6 +5164,10 @@ msgstr "direktori git" msgid "separate git dir from working tree" msgstr "pisahkan direktori git dari pohon kerja" +#: builtin/clone.c builtin/init-db.c +msgid "specify the reference format to use" +msgstr "sebutkan format referensi untuk digunakan" + #: builtin/clone.c msgid "key=value" msgstr "kunci=nilai" @@ -5299,13 +5318,10 @@ msgstr "Terlalu banyak argumen." msgid "You must specify a repository to clone." msgstr "Anda harus sebutkan repositori untuk diklon." -#: builtin/clone.c -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "" -"--bundle-uri tidak kompatibel dengan --depth, --shallow-since, dan --shallow-" -"exclude" +#: builtin/clone.c builtin/init-db.c setup.c +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "format penyimpanan referensi tidak dikenal '%s'" #: builtin/clone.c #, c-format @@ -5471,13 +5487,13 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <direktori>] [--append]\n" " [--split[=<strategi>]] [--reachable | --stdin-packs | " "--stdin-commits]\n" -" [--changed-paths] [--[no-]max-new-filters <n>] [--[-" -"no-]progress]\n" +" [--changed-paths] [--[no-]max-new-filters <n>] [--" +"[no-]progress]\n" " <opsi pemisahan>" #: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c @@ -5499,6 +5515,11 @@ msgstr "Tidak dapat membuka grafik komit '%s'" #: builtin/commit-graph.c #, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "tidak dapat membuka grafik komit '%s'" + +#: builtin/commit-graph.c +#, c-format msgid "unrecognized --split argument, %s" msgstr "argumen --split tidak dikenal, %s" @@ -5743,10 +5764,6 @@ msgid "Failed to update main cache tree" msgstr "gagal memperbarui tembolok pohon utama" #: builtin/commit.c -msgid "unable to write new_index file" -msgstr "tidak dapat menulis berkas new_index" - -#: builtin/commit.c msgid "cannot do a partial commit during a merge." msgstr "tidak dapat melakukan komit sebagian selama penggabungan." @@ -6244,11 +6261,11 @@ msgstr "Batalkan komit karena badan pesan komit kosong.\n" #: builtin/commit.c msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" "repositori sudah diperbarui, tetapi tidak dapat menulis\n" -"berkas new_index. Periksa bahwa disk tidak penuh dan kuota\n" +"berkas indeks baru. Periksa bahwa disk tidak penuh dan kuota\n" "tidak terlampaui, lalu \"git restore --staged :/\" untuk pulihkan." #: builtin/config.c @@ -8085,6 +8102,10 @@ msgstr "pangkas objek tak tereferensi" msgid "pack unreferenced objects separately" msgstr "pak objek tak terujuk secara terpisah" +#: builtin/gc.c builtin/repack.c +msgid "with --cruft, limit the size of new cruft packs" +msgstr "batasi ukuran pak sisa dengan --cruft" + #: builtin/gc.c msgid "be more thorough (increased runtime)" msgstr "jadi lebih cermat (waktu yang dijalankan bertambah)" @@ -8306,14 +8327,6 @@ msgstr "" msgid "'crontab' died" msgstr "'crontab' mati" -#: builtin/gc.c -msgid "failed to start systemctl" -msgstr "gagal memulai systemctl" - -#: builtin/gc.c -msgid "failed to run systemctl" -msgstr "gagal menjalankan systemctl" - #: builtin/gc.c builtin/worktree.c #, c-format msgid "failed to delete '%s'" @@ -8325,6 +8338,14 @@ msgid "failed to flush '%s'" msgstr "gagal membilas '%s'" #: builtin/gc.c +msgid "failed to start systemctl" +msgstr "gagal memulai systemctl" + +#: builtin/gc.c +msgid "failed to run systemctl" +msgstr "gagal menjalankan systemctl" + +#: builtin/gc.c #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "argumen --scheduler tidak dikenal '%s'" @@ -8355,6 +8376,10 @@ msgid "scheduler to trigger git maintenance run" msgstr "penjadwal untuk memicu git maintenance run" #: builtin/gc.c +msgid "failed to set up maintenance schedule" +msgstr "gagal mempersiapkan jadwal pemeliharaan" + +#: builtin/gc.c msgid "failed to add repo to global config" msgstr "gagal menambahkan repositori ke konfigurasi global" @@ -8393,6 +8418,11 @@ msgstr "tidak dapat membaca pohon (%s)" #: builtin/grep.c #, c-format +msgid "unable to read tree %s" +msgstr "tidak dapat membaca pohon %s" + +#: builtin/grep.c +#, c-format msgid "unable to grep from object of type %s" msgstr "tidak dapan men-grep dari objek dengan tipe %s" @@ -8450,7 +8480,7 @@ msgid "search in subdirectories (default)" msgstr "cari dalam subdirektori (asali)" #: builtin/grep.c -msgid "descend at most <depth> levels" +msgid "descend at most <n> levels" msgstr "turun paling banyak <kedalaman> tingkat" #: builtin/grep.c @@ -8920,11 +8950,6 @@ msgstr "inkonsistensi inflate serius" msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "TUMBUKAN SHA1 DITEMUKAN DENGAN %s !" -#: builtin/index-pack.c builtin/pack-objects.c -#, c-format -msgid "unable to read %s" -msgstr "tidak dapat membaca %s" - #: builtin/index-pack.c #, c-format msgid "cannot read existing object info %s" @@ -9102,11 +9127,13 @@ msgstr "kesalahan fsck dalam objek paket" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" "git init [-q | --quiet] [--bare] [--template=<direktori templat>]\n" " [--separate-git-dir <direktori git>] [--object-format=<format>]\n" +"\t [--ref-format=<format>]\n" " [-b <nama cabang> | --initial-branch=<nama cabang>]\n" " [--shared[=<perizinan>]] [<direktori>]" @@ -9162,11 +9189,12 @@ msgstr "--separate-git-dir tidak kompatibel dengan repositori bare" #: builtin/interpret-trailers.c msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<nilai>])...]\n" +" [(--trailer (<kunci>|<alias kunci>)" +"[(=|:)<nilai>])...]\n" " [--parse] [<berkas>...]" #: builtin/interpret-trailers.c @@ -9178,6 +9206,10 @@ msgid "trim empty trailers" msgstr "pangkas trailer kosong" #: builtin/interpret-trailers.c +msgid "placement" +msgstr "penempatan" + +#: builtin/interpret-trailers.c msgid "where to place the new trailer" msgstr "dimana trailer baru ditempatkan" @@ -9194,20 +9226,20 @@ msgid "output only the trailers" msgstr "keluarkan hanya trailer" #: builtin/interpret-trailers.c -msgid "do not apply config rules" -msgstr "jangan terapkan aturan konfigurasi" +msgid "do not apply trailer.* configuration variables" +msgstr "jangan terapkan variabel konfigurasi trailer.*" #: builtin/interpret-trailers.c -msgid "join whitespace-continued values" -msgstr "gabungkan nilai yang dilanjutkan oleh spasi" +msgid "reformat multiline trailer values as single-line values" +msgstr "format ulang nilai trailer multibaris sebagai nilai satu baris." #: builtin/interpret-trailers.c -msgid "set parsing options" -msgstr "setel opsi penguraian" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "alias untuk --only-trailers --only-input --unfold" #: builtin/interpret-trailers.c -msgid "do not treat --- specially" -msgstr "jangan memperlakukan khusus ---" +msgid "do not treat \"---\" as the end of input" +msgstr "jangan perlakukan \"---\" sebagai ujung masukan" #: builtin/interpret-trailers.c msgid "trailer(s) to add" @@ -9266,7 +9298,7 @@ msgstr "" "lacak evolusi rentang baris <awal>,<akhir> atau fungsi :<nama fungsi> dalam " "<berkas>" -#: builtin/log.c builtin/shortlog.c bundle.c +#: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c #, c-format msgid "unrecognized argument: %s" msgstr "argumen tidak dikenal: %s" @@ -9322,6 +9354,11 @@ msgid "not a range" msgstr "bukan sebuah rentang" #: builtin/log.c +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "tidak dapat membaca berkas deskripsi cabang '%s'" + +#: builtin/log.c msgid "cover letter needs email format" msgstr "sampul surat butuh format email" @@ -9450,6 +9487,10 @@ msgid "generate parts of a cover letter based on a branch's description" msgstr "buat bagian dari sampul surat berdasarkan deskripsi cabang" #: builtin/log.c +msgid "use branch description from file" +msgstr "gunakan deskripsi cabang dari berkas" + +#: builtin/log.c msgid "use [<prefix>] instead of [PATCH]" msgstr "gunakan [<prefix>] daripada [PATCH]" @@ -10013,11 +10054,23 @@ msgstr "" "git merge-file [<opsi>] [-L <nama 1> [-L <asli> [-L <nama 2>]]] <berkas 1> " "<berkas asli> <berkas 2>" +#: builtin/merge-file.c diff.c +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"opsi diff-algorithm terima \"myers\", \"minimal\", \"patience\" dan " +"\"histogram\"" + #: builtin/merge-file.c msgid "send results to standard output" msgstr "kirim hasil ke keluaran standar" #: builtin/merge-file.c +msgid "use object IDs instead of filenames" +msgstr "gunakan ID objek daripada nama berkas" + +#: builtin/merge-file.c msgid "use a diff3 based merge" msgstr "gunakan penggabungan berdasarkan diff3" @@ -10037,6 +10090,14 @@ msgstr "untuk konflik, gunakan versi mereka" msgid "for conflicts, use a union version" msgstr "untuk konflik, gunakan versi bersatu" +#: builtin/merge-file.c diff.c +msgid "<algorithm>" +msgstr "<algoritma>" + +#: builtin/merge-file.c diff.c +msgid "choose a diff algorithm" +msgstr "pilih algoritma diff" + #: builtin/merge-file.c msgid "for conflicts, use this marker size" msgstr "untuk konflik, gunakan ukuran penanda ini" @@ -10049,6 +10110,15 @@ msgstr "jangan peringatkan tentang konflik" msgid "set labels for file1/orig-file/file2" msgstr "setel label untuk file1/orig-file/file2" +#: builtin/merge-file.c +#, c-format +msgid "object '%s' does not exist" +msgstr "objek '%s' tidak ada" + +#: builtin/merge-file.c +msgid "Could not write object file" +msgstr "Tidak dapat menulis berkas objek" + #: builtin/merge-recursive.c #, c-format msgid "unknown option %s" @@ -10128,13 +10198,22 @@ msgstr "lakukan banyak penggabungan, satu per baris masukan" msgid "specify a merge-base for the merge" msgstr "harus menyebutkan sebuah dasar penggabungan untuk penggabungan" +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c +msgid "option=value" +msgstr "opsi=nilai" + +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c +msgid "option for selected merge strategy" +msgstr "opsi untuk strategi penggabungan yang dipilih" + #: builtin/merge-tree.c msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge tidak kompatibel dengan semua opsi lainnya" -#: builtin/merge-tree.c -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base tidak kompatibel dengan --stdin" +#: builtin/merge-tree.c builtin/merge.c +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "opsi strategi tidak dikenal: -X%s" #: builtin/merge-tree.c builtin/notes.c #, c-format @@ -10224,14 +10303,6 @@ msgstr "strategi" msgid "merge strategy to use" msgstr "strategi penggabungan yang digunakan" -#: builtin/merge.c builtin/pull.c -msgid "option=value" -msgstr "opsi=nilai" - -#: builtin/merge.c builtin/pull.c -msgid "option for selected merge strategy" -msgstr "opsi untuk strategi penggabungan yang dipilih" - #: builtin/merge.c msgid "merge commit message (for a non-fast-forward merge)" msgstr "pesan komit penggabungan (untuk penggabungan bukan maju cepat)" @@ -10301,7 +10372,7 @@ msgstr "'%s' tidak menunjuk pada sebuah komit" msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Untai branch.%s.mergeoptions jelek: %s" -#: builtin/merge.c builtin/stash.c merge-recursive.c +#: builtin/merge.c merge-recursive.c msgid "Unable to write index." msgstr "Tidak dapat menulis indeks." @@ -10311,11 +10382,6 @@ msgstr "Tak tangani apapun selain penggabungan dua kepala." #: builtin/merge.c #, c-format -msgid "unknown strategy option: -X%s" -msgstr "opsi strategi tidak dikenal: -X%s" - -#: builtin/merge.c t/helper/test-fast-rebase.c -#, c-format msgid "unable to write %s" msgstr "tidak dapat menulis %s" @@ -10682,8 +10748,8 @@ msgid "can not move directory into itself" msgstr "tidak dapat memindahkan direktori ke dirinya sendiri" #: builtin/mv.c -msgid "cannot move directory over file" -msgstr "tidak dapat memindahkan direktori ke berkas" +msgid "destination already exists" +msgstr "tujuan sudah ada" #: builtin/mv.c msgid "source directory is empty" @@ -11329,6 +11395,11 @@ msgstr "ketidakkonsistenan dengan hitungan delta" #: builtin/pack-objects.c #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "nilai pack.allowPackReuse tidak valid: '%s'" + +#: builtin/pack-objects.c +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -11635,10 +11706,6 @@ msgstr "" "--thin tidak dapat digunakan untuk membangun sebuah pak yang dapat diindeks" #: builtin/pack-objects.c -msgid "cannot use --filter without --stdout" -msgstr "tidak dapat menggunakan --filter tanpa --stdout" - -#: builtin/pack-objects.c msgid "cannot use --filter with --stdin-packs" msgstr "tidak dapat menggunakan --filter dengan --stdin-packs" @@ -11655,10 +11722,6 @@ msgid "cannot use --stdin-packs with --cruft" msgstr "tidak dapat menggunakan --stdin-packs dengan --cruft" #: builtin/pack-objects.c -msgid "cannot use --max-pack-size with --cruft" -msgstr "tidak dapat menggunakan --max-pack-size dengan --cruft" - -#: builtin/pack-objects.c msgid "Enumerating objects" msgstr "Menghitung objek" @@ -11666,10 +11729,10 @@ msgstr "Menghitung objek" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "Total %<PRIu32> (delta %<PRIu32>), digunakan ulang %<PRIu32> (delta " -"%<PRIu32>), pak yang digunakan ulang %<PRIu32>" +"%<PRIu32>), pak yang digunakan ulang %<PRIu32> (dari %<PRIuMAX>)" #: builtin/pack-redundant.c msgid "" @@ -12788,7 +12851,7 @@ msgid "The --edit-todo action can only be used during interactive rebase." msgstr "" "Aksi --edit-todo hanya dapat digunakan selama pendasaran ulang interaktif." -#: builtin/rebase.c t/helper/test-fast-rebase.c +#: builtin/rebase.c msgid "Cannot read HEAD" msgstr "Tidak dapat membaca HEAD" @@ -12835,18 +12898,6 @@ msgid "switch `C' expects a numerical value" msgstr "tombol `C' harap nilai numerik" #: builtin/rebase.c -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy butuh --merge atau --interactive" - -#: builtin/rebase.c -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "" -"opsi penerapan tidak kompatibel dengan rebase.autoSquash. " -"Pertimbangkanmenambahkan --no-autosquash" - -#: builtin/rebase.c msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -13344,10 +13395,10 @@ msgid_plural "" "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n" "to delete them, use:" msgstr[0] "" -"Catatan: Sebuah cabang diluar hierarki refs/remotes tidak dihapus;\n" +"Catatan: Sebuah cabang diluar hierarki refs/remotes/ tidak dihapus;\n" "untuk menghapusnya, gunakan:" msgstr[1] "" -"Catatan: Beberapa cabang diluar hierarki refs/remotes tidak dihapus;\n" +"Catatan: Beberapa cabang diluar hierarki refs/remotes/ tidak dihapus;\n" "untuk menghapusnya, gunakan:" #: builtin/remote.c @@ -13708,6 +13759,11 @@ msgid "could not remove stale bitmap: %s" msgstr "tidak dapt memindahkan bitmap basi: %s" #: builtin/repack.c +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "nama berkas paket %s tidak diawali dengan %s" + +#: builtin/repack.c msgid "pack everything in a single pack" msgstr "pak semuanya dalam satu pak" @@ -13810,17 +13866,21 @@ msgid "pack prefix to store a pack containing pruned objects" msgstr "awalan pak untuk menyimpan pak berisi objek terpangkas" #: builtin/repack.c +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "awalan pak untuk menyimpan pak berisi objek tersaring" + +#: builtin/repack.c msgid "cannot delete packs in a precious-objects repo" msgstr "tidak dapat menghapus pak dalam repositori objek berharga" #: builtin/repack.c -msgid "Nothing new to pack." -msgstr "Tidak ada yang baru untuk dipak." +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "opsi '%s' tidak dapat digunakan bersamaan dengan '%s'" #: builtin/repack.c -#, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "nama berkas paket %s tidak diawali dengan %s" +msgid "Nothing new to pack." +msgstr "Tidak ada yang baru untuk dipak." #: builtin/repack.c #, c-format @@ -14075,6 +14135,94 @@ msgstr "--convert-graft-file tidak mengambil argumen" msgid "only one pattern can be given with -l" msgstr "hanya satu pola yang dapat diberikan dengan -l" +#: builtin/replay.c +msgid "need some commits to replay" +msgstr "butuh beberapa komit untuk dimainkan ulang" + +#: builtin/replay.c +msgid "--onto and --advance are incompatible" +msgstr "--onto dan --advance tidak kompatibel" + +#: builtin/replay.c +msgid "all positive revisions given must be references" +msgstr "semua revisi positif yang diberikan haruslah referensi" + +#: builtin/replay.c +msgid "argument to --advance must be a reference" +msgstr "argumen pada --advance harus sebuah referensi" + +#: builtin/replay.c +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "" +"tidak dapat memajukan target dengan banyak sumber karena pengurutannya akan " +"menjadi tidak jelas" + +#: builtin/replay.c +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "" +"tidak dapat menentukan secara tidak langsung apakah ini operasi --advance " +"atau --onto" + +#: builtin/replay.c +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "" +"tidak dapat memajukan target dengan banyak cabang sumber karena " +"pengurutannya akan menjadi tidak jelas" + +#: builtin/replay.c +msgid "cannot implicitly determine correct base for --onto" +msgstr "tidak dapat menentukan secara tidak langsung dasar untuk --onto" + +#: builtin/replay.c +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(EKSPERIMENTAL!) git replay ([--contained] --onto <dasar baru> | --advance " +"<cabang>) <rentang revisi>..." + +#: builtin/replay.c +msgid "make replay advance given branch" +msgstr "buat pemainan ulang memajukan caban yang diberikan" + +#: builtin/replay.c +msgid "replay onto given commit" +msgstr "mainkan ulang pada komit yang diberikan" + +#: builtin/replay.c +msgid "advance all branches contained in revision-range" +msgstr "majukan semua cabang yang berada pada rentang komit" + +#: builtin/replay.c +msgid "option --onto or --advance is mandatory" +msgstr "opsi --onto atau --advance diwajibkan" + +#: builtin/replay.c +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "" +"beberapa opsi jalan revisi akan ditimpa oleh karena bit '%s' di 'struct " +"rev_info' akan dipaksakan" + +#: builtin/replay.c +msgid "error preparing revisions" +msgstr "kesalahan menyiapkan revisi" + +#: builtin/replay.c +msgid "replaying down to root commit is not supported yet!" +msgstr "memainkan ulang ke komit akar belum didukung!" + +#: builtin/replay.c +msgid "replaying merge commits is not supported yet!" +msgstr "memainkan ulang komit penggabungan belum didukung!" + #: builtin/rerere.c msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" @@ -14337,23 +14485,15 @@ msgstr "--prefix butuh sebuah argumen" msgid "unknown mode for --abbrev-ref: %s" msgstr "mode untuk --abbrev-ref tidak dikenal: %s" -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden tidak dapat digunakan bersamaan dengan --branches" - -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden tidak dapat digunakan bersamaan dengan --tags" - -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden tidak dapat digunakan dengan --remotes" - #: builtin/rev-parse.c setup.c msgid "this operation must be run in a work tree" msgstr "operasi ini harus dijalankan di dalam pohon kerja" #: builtin/rev-parse.c +msgid "Could not read the index" +msgstr "Tidak dapat membaca indeks" + +#: builtin/rev-parse.c #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "mode untuk --show-object-format tidak dikenal: %s" @@ -14785,11 +14925,21 @@ msgstr "algoritma hash tidak dikenal" #: builtin/show-ref.c msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" +" [--heads] [--] [<pola>...]" + +#: builtin/show-ref.c +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pola>...]" @@ -14798,6 +14948,18 @@ msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<pola>]" #: builtin/show-ref.c +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <referensi>" + +#: builtin/show-ref.c +msgid "reference does not exist" +msgstr "referensi tidak ada" + +#: builtin/show-ref.c +msgid "failed to look up reference" +msgstr "gagal mencari referensi" + +#: builtin/show-ref.c msgid "only show tags (can be combined with heads)" msgstr "hanya perlihatkan tag (bisa dikombinasikan dengan kepala)" @@ -14806,6 +14968,10 @@ msgid "only show heads (can be combined with tags)" msgstr "hanya perlihatkan kepala (bisa dikombinasikan dengan tag)" #: builtin/show-ref.c +msgid "check for reference existence without resolving" +msgstr "periksa adanya referensi tanpa penguraian" + +#: builtin/show-ref.c msgid "stricter reference checking, requires exact ref path" msgstr "pemeriksaan referensi lebih ketat, butuh jalur referensi eksak" @@ -15827,6 +15993,10 @@ msgstr "" "shallow] [--reference <repositori>] [--recursive] [--[no-]single-branch] " "[--] [<jalur>...]" +#: builtin/submodule--helper.c submodule.c +msgid "Failed to resolve HEAD as a valid ref." +msgstr "Gagal menguraikan HEAD sebagai referensi valid." + #: builtin/submodule--helper.c msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<opsi>] [<jalur>...]" @@ -16409,6 +16579,10 @@ msgid "write index in this format" msgstr "tulis indeks dalam format ini" #: builtin/update-index.c +msgid "report on-disk index format version" +msgstr "laporkan versi format indeks pada-disk" + +#: builtin/update-index.c msgid "enable or disable split index" msgstr "aktifkan atau nonaktifkan indeks terpisah" @@ -16441,6 +16615,16 @@ msgid "clear fsmonitor valid bit" msgstr "bersihkan bita fsmonitor valid" #: builtin/update-index.c +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#: builtin/update-index.c +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "index-version: sebelumnya %d, disetel ke %d" + +#: builtin/update-index.c msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -16634,7 +16818,7 @@ msgstr "Tidak ada cabang sumber yang mungkin, menyimpulkan '--orphan'" #: builtin/worktree.c #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" @@ -16648,7 +16832,7 @@ msgstr "" #: builtin/worktree.c #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" @@ -16728,6 +16912,11 @@ msgstr "menginisialisasi" #: builtin/worktree.c #, c-format +msgid "could not find created worktree '%s'" +msgstr "tidak dapat menemukan pohon kerja yang dibuat '%s'" + +#: builtin/worktree.c +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "Menyiapkan pohon kerja (cabang baru '%s')" @@ -16766,17 +16955,11 @@ msgstr "" #: builtin/worktree.c msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" "Tidak ada referensi lokal atau remote yang ada meskipun salah satu remote\n" -"ada, berhenti. Gunakan 'add -f' untuk menimpa atau mengambil remote " -"terlebih\n" -"dahulu" - -#: builtin/worktree.c -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "'%s' dan '%s' tidak dapat digunakan bersamaan" +"ada, berhenti; gunakan 'add -f' untuk menimpa atau mengambil remote\n" +"terlebih dahulu" #: builtin/worktree.c msgid "checkout <branch> even if already checked out in other worktree" @@ -16792,7 +16975,7 @@ msgid "create or reset a branch" msgstr "buat atau setel ulang sebuah cabang" #: builtin/worktree.c -msgid "create unborn/orphaned branch" +msgid "create unborn branch" msgstr "buat cabang belum lahir/yatim" #: builtin/worktree.c @@ -16822,12 +17005,8 @@ msgstr "Opsi '%s', '%s', dan '%s' tidak dapat digunakan bersamaan" #: builtin/worktree.c #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "Opsi '%s', dan '%s' tidak dapat digunakan bersamaan" - -#: builtin/worktree.c -msgid "<commit-ish>" -msgstr "<mirip-komit>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "opsi '%s' dan mirip-komit tidak dapat digunakan bersamaan" #: builtin/worktree.c msgid "added with --lock" @@ -17170,6 +17349,11 @@ msgstr "id bingkah pengakhiran muncul lebih awal dari yang diharapkan" #: chunk-format.c #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "id bingkah %<PRIx32> tidak terata %d-bita" + +#: chunk-format.c +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "offset bingkah %<PRIx64> dan %<PRIx64> tidak tepat" @@ -17239,9 +17423,8 @@ msgid "Move objects and refs by archive" msgstr "Pindahkan objek dan referensi oleh arsip" #: command-list.h -msgid "Provide content or type and size information for repository objects" -msgstr "" -"Sediakan isi atau informasi tipe dan ukuran berkas untuk objek repositori" +msgid "Provide contents or details of repository objects" +msgstr "Sediakan isi atau detail objek repositori" #: command-list.h msgid "Display gitattributes information" @@ -17626,6 +17809,12 @@ msgid "Create, list, delete refs to replace objects" msgstr "Buat, daftar, hapus referensi untuk mengganti objek" #: command-list.h +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "" +"EKSPERIMENTAL: Mainkan ulang komit pada dasar baru, dan juga bekerja pada " +"repositori bare" + +#: command-list.h msgid "Generates a summary of pending changes" msgstr "Buat ringkasan perubahan tertunda" @@ -17787,8 +17976,8 @@ msgid "Display version information about Git" msgstr "Perlihatkan info versi Git" #: command-list.h -msgid "Show logs with difference each commit introduces" -msgstr "Perlihatkan log dengan perbedaan yang dimasukkan setiap komit" +msgid "Show logs with differences each commit introduces" +msgstr "Perlihatkan log dengan perbedaan yang diperkenalkan pada setiap komit" #: command-list.h msgid "Manage multiple working trees" @@ -17943,6 +18132,39 @@ msgid "commit-graph file is too small" msgstr "berkas grafik komit terlalu kecil" #: commit-graph.c +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "bingkah oid grafik komit kipas keluar salah ukuran" + +#: commit-graph.c +msgid "commit-graph fanout values out of order" +msgstr "nilai kipas keluar grafik komit tidak berurutan" + +#: commit-graph.c +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "bingkah OID pencarian grafik komit salah ukuran" + +#: commit-graph.c +msgid "commit-graph commit data chunk is wrong size" +msgstr "bingkah data grafik komit salah ukuran" + +#: commit-graph.c +msgid "commit-graph generations chunk is wrong size" +msgstr "bingkah generasi grafik komit salah ukuran" + +#: commit-graph.c +msgid "commit-graph changed-path index chunk is too small" +msgstr "bingkah indeks grafik komit jalur berubah terlalu kecil" + +#: commit-graph.c +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "" +"mengabaikan bingkah jalur berubah yang terlalu kecil (%<PRIuMAX> < " +"%<PRIuMAX>) di dalam berkas grafik komit" + +#: commit-graph.c #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "tanda tangan grafik komit %X tidak cocok dengan tanda tangan %X" @@ -17963,10 +18185,27 @@ msgid "commit-graph file is too small to hold %u chunks" msgstr "berkas grafik komit terlalu kecil untuk menyimpan %u bingkah" #: commit-graph.c +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "" +"bingkah grafik komit OID kipas keluar yang diperlukan hilang atau rusak" + +#: commit-graph.c +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "bingkah grafik komit OID pencarian yang diperlukan hilang atau rusak" + +#: commit-graph.c +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "bingkah grafik komit data komit yang diperlukan hilang atau rusak" + +#: commit-graph.c msgid "commit-graph has no base graphs chunk" msgstr "grafik komit tidak punya bingkah grafik dasar" #: commit-graph.c +msgid "commit-graph base graphs chunk is too small" +msgstr "bingkah grafik komit dasar terlalu kecil" + +#: commit-graph.c msgid "commit-graph chain does not match" msgstr "rantai grafik komit tidak cocok" @@ -17976,6 +18215,10 @@ msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "jumlah komit pada grafik dasar terlalu tinggi: %<PRIuMAX>" #: commit-graph.c +msgid "commit-graph chain file too small" +msgstr "berkas rantai grafik komit terlalu kecil" + +#: commit-graph.c #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" msgstr "rantai grafik komit tidak cocok: baris '%s' bukan sebuah hash" @@ -17998,6 +18241,14 @@ msgid "commit-graph requires overflow generation data but has none" msgstr "grafik komit memerlukan pembuatan data meluap tapi tidak punya" #: commit-graph.c +msgid "commit-graph overflow generation data is too small" +msgstr "data generasi luapan grafik komit terlalu kecil" + +#: commit-graph.c +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "penunjuk tepi tambahan grafik komit di luar batas" + +#: commit-graph.c msgid "Loading known commits in commit graph" msgstr "Memuat komit yang dikenal di grafik komit" @@ -18154,22 +18405,6 @@ msgstr "daftar induk grafik komit untuk komit %s berakhir lebih awal" #: commit-graph.c #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" -"grafik komit punya angka pembuatan nol untuk komit %s, tapi bukan nol di " -"tempat lain" - -#: commit-graph.c -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" -"grafik komit punya angka pembuatan bukan nol untuk komit %s, tapi nol di " -"tempat lain" - -#: commit-graph.c -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "pembuatan grafik komit untuk komit %s yaitu %<PRIuMAX> < %<PRIuMAX>" @@ -18181,6 +18416,15 @@ msgstr "" "%<PRIuMAX>" #: commit-graph.c +#, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "" +"grafik komit punya baik generasi nol dan bukan nol (seperti komit '%s' dan " +"'%s')" + +#: commit-graph.c msgid "Verifying commits in commit graph" msgstr "Memverifikasi komit di dalam grafik komit" @@ -18211,6 +18455,12 @@ msgstr "" #: commit.c #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "" +"komit %s ada pada grafik komit tapi tidak ada di dalam basis data objek" + +#: commit.c +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "Komit %s punya tandatangan GPG tak dipercaya, dituduh sebagai %s." @@ -18758,11 +19008,6 @@ msgid "unable to resolve config blob '%s'" msgstr "tidak dapat menguraikan blob konfigurasi '%s'" #: config.c -#, c-format -msgid "failed to parse %s" -msgstr "gagal menguraikan %s" - -#: config.c msgid "unable to parse command-line config" msgstr "gagal menguraikan konfigurasi baris perintah" @@ -19342,10 +19587,6 @@ msgid "--merge-base does not work with ranges" msgstr "--merge-base tidak bekerja dengan rentang" #: diff-lib.c -msgid "--merge-base only works with commits" -msgstr "--merge-base hanya bekerja dengan komit" - -#: diff-lib.c msgid "unable to get HEAD" msgstr "tidak dapat mendapatkan HEAD" @@ -19418,6 +19659,11 @@ msgstr "" msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "Nilai tidak dikenal untuk variabel konfigurasi 'diff.submodule': '%s'" +#: diff.c transport.c +#, c-format +msgid "unknown value for config '%s': %s" +msgstr "nilai tidak dikenal untuk konfigurasi '%s': %s" + #: diff.c #, c-format msgid "" @@ -19515,14 +19761,6 @@ msgid "invalid mode '%s' in --color-moved-ws" msgstr "mode tidak valid '%s' dalam --color-moved-ws" #: diff.c -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"opsi diff-algorithm terima \"myers\", \"minimal\", \"patience\" dan " -"\"histogram\"" - -#: diff.c #, c-format msgid "invalid argument to %s" msgstr "argumen tidak valid ke %s" @@ -19579,8 +19817,8 @@ msgid "output only the last line of --stat" msgstr "keluarkan hanya baris terakhir --stat" #: diff.c -msgid "<param1,param2>..." -msgstr "<parameter 1,parameter 2>..." +msgid "<param1>,<param2>..." +msgstr "<parameter 1>,<parameter 2>..." #: diff.c msgid "" @@ -19593,8 +19831,8 @@ msgid "synonym for --dirstat=cumulative" msgstr "sinonim untuk --dirstat=cumulative" #: diff.c -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "sinonim untuk --dirstat=files,param1,param2..." +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "sinonim untuk --dirstat=files,<parameter 1>,<parameter 2>..." #: diff.c msgid "warn if changes introduce conflict markers or whitespace errors" @@ -19827,14 +20065,6 @@ msgid "generate diff using the \"histogram diff\" algorithm" msgstr "buat diff menggunakan algoritma \"diff histogram\"" #: diff.c -msgid "<algorithm>" -msgstr "<algoritma>" - -#: diff.c -msgid "choose a diff algorithm" -msgstr "pilih algoritma diff" - -#: diff.c msgid "<text>" msgstr "<teks>" @@ -21113,13 +21343,13 @@ msgstr "" "%s" #: merge-ort.c merge-recursive.c -msgid "Failed to execute internal merge" -msgstr "Gagal menjalankan penggabungan internal" +msgid "failed to execute internal merge" +msgstr "gagal menjalankan penggabungan internal" #: merge-ort.c merge-recursive.c #, c-format -msgid "Unable to add %s to database" -msgstr "Tidak dapat menambahkan %s ke basis data" +msgid "unable to add %s to database" +msgstr "tidak dapat menambahkan %s ke basis data" #: merge-ort.c merge-recursive.c #, c-format @@ -21644,6 +21874,22 @@ msgstr "OID kipas-keluar indeks multipak salah ukuran" #: midx.c #, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"kipas-keluar oid tidak berurutan: fanout[%d] =%<PRIx32> > %<PRIx32> = " +"fanout[%d]" + +#: midx.c +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "bingkah pencarian OID kipas-keluar indeks multipak salah ukuran" + +#: midx.c +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "bingkah offset OID kipas-keluar indeks multipak salah ukuran" + +#: midx.c +#, c-format msgid "multi-pack-index file %s is too small" msgstr "berkas indeks multipak %s terlalu kecil" @@ -21664,20 +21910,26 @@ msgid "multi-pack-index hash version %u does not match version %u" msgstr "versi hash indeks multipak %u tidak cocok dengan versi %u" #: midx.c -msgid "multi-pack-index missing required pack-name chunk" -msgstr "indeks multipak kehilangan bingkah pack-name yang diperlukan" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "bingkah nama pak indeks multipak yang diperlukan hilang atau rusak" #: midx.c -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "indeks multipak kehilangan bingkah OID kipas keluar yang diperlukan" +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "" +"bingkah OID kipas-keluar indeks multipak yang diperlukan hilang atau rusak" #: midx.c -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "indeks multipak kehilangan bingkah pencarian OID yang diperlukan" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "" +"bingkah pencarian OID indeks multipak yang diperlukan hilang atau rusak" #: midx.c -msgid "multi-pack-index missing required object offsets chunk" -msgstr "indeks multipak kehilangan bingkah offset objek yang diperlukan" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "bingkah offset objek indeks multipak yang diperlukan hilang atau rusak" + +#: midx.c +msgid "multi-pack-index pack-name chunk is too short" +msgstr "bingkah nama pak indeks multipak terlalu kecil" #: midx.c #, c-format @@ -21690,10 +21942,23 @@ msgid "bad pack-int-id: %u (%u total packs)" msgstr "pack-int-id jelek: %u (total pak %u)" #: midx.c +msgid "MIDX does not contain the BTMP chunk" +msgstr "MIDX tidak berisi bingkah BTMP" + +#: midx.c +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "tidak dapat membuka pak terbitmap %<PRIu32>" + +#: midx.c msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "indeks multipak simpan offset 64-bit, tapi off_t terlalu kecil" #: midx.c +msgid "multi-pack-index large offset out of bounds" +msgstr "offset indeks multipak besar di luar jangkauan" + +#: midx.c #, c-format msgid "failed to add packfile '%s'" msgstr "gagal menambah berkas pak '%s'" @@ -21793,14 +22058,6 @@ msgid "Looking for referenced packfiles" msgstr "Mencari berkas pak yang direferensikan" #: midx.c -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "" -"kipas-keluar oid tidak berurutan: fanout[%d] =%<PRIx32> > %<PRIx32> = " -"fanout[%d]" - -#: midx.c msgid "the midx contains no oid" msgstr "midx tidak berisi oid" @@ -22437,6 +22694,10 @@ msgstr "bitmap multipak kehilangan indeks balik yang diperlukan" msgid "could not open pack %s" msgstr "tidak dapat membuka '%s'" +#: pack-bitmap.c t/helper/test-read-midx.c +msgid "could not determine MIDX preferred pack" +msgstr "tidak dapat menentukan pak MIDX terpilih" + #: pack-bitmap.c #, c-format msgid "preferred pack (%s) is invalid" @@ -22462,6 +22723,11 @@ msgstr "bitmap ewah rusak: kepala terpotong untuk bitmap komit \"%s\"" #: pack-bitmap.c #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "tidak dapat memuat pak: '%s', mematikan penggunaan ulang pak" + +#: pack-bitmap.c +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "objek '%s' tidak ditemukan di bitmap tipe" @@ -22571,6 +22837,14 @@ msgstr "checksum tidak valid" msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "posisi indeks balik tidak valid pada %<PRIu64>: %<PRIu32> != %<PRIu32>" +#: pack-revindex.c +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "bingkah indeks balik multipak salah ukuran" + +#: pack-revindex.c +msgid "could not determine preferred pack" +msgstr "tidak dapat menentukan pak terpilih" + #: pack-write.c msgid "cannot both write and verify reverse index" msgstr "tidak dapat kedua-duanya menulis dan memverifikasi indeks balik" @@ -22636,16 +22910,6 @@ msgstr "%s butuh sebuah nilai" #: parse-options.c #, c-format -msgid "%s is incompatible with %s" -msgstr "%s tidak kompatibel dengan %s" - -#: parse-options.c -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s : tidak kompatibel dengan sesuatu yang lain" - -#: parse-options.c -#, c-format msgid "%s takes no value" msgstr "%s tidak mengambil nilai apapun" @@ -22745,6 +23009,11 @@ msgstr " %s" msgid "-NUM" msgstr "-NUM" +#: parse-options.c +#, c-format +msgid "opposite of --no-%s" +msgstr "lawan dari --no-%s" + #: parse-options.h msgid "expiry-date" msgstr "tanggal kadaluarsa" @@ -22783,6 +23052,16 @@ msgid "" msgstr "" "dengan --pathspec-from-file, elemen spek jalur dipisahkan dengan karakter NUL" +#: parse.c +#, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "nilai lingkungan boolean '%s' jelek untuk '%s'" + +#: parse.c +#, c-format +msgid "failed to parse %s" +msgstr "gagal menguraikan %s" + #: path.c #, c-format msgid "Could not make %s writable by group" @@ -22845,6 +23124,11 @@ msgstr "%s: 'literal' dan 'glob' tidak kompatibel" #: pathspec.c #, c-format +msgid "'%s' is outside the directory tree" +msgstr "'%s' di luar pohon direktori" + +#: pathspec.c +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s: '%s' di luar repositori pada '%s'" @@ -23042,11 +23326,6 @@ msgstr "tidak dapat menambahkan '%s' ke indeks" #: read-cache.c #, c-format -msgid "unable to stat '%s'" -msgstr "tidak dapat men-stat '%s'" - -#: read-cache.c -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "'%s' muncul baik sebagai sebuah berkas dan sebagai sebuah direktori" @@ -23180,11 +23459,6 @@ msgstr "gagal mengubah ke indeks jarang" #: read-cache.c #, c-format -msgid "could not stat '%s'" -msgstr "tidak dapat men-stat '%s'" - -#: read-cache.c -#, c-format msgid "unable to open git dir: %s" msgstr "tidak dapat membuka direktori git: %s" @@ -23736,17 +24010,12 @@ msgstr "'%s' ada; tidak dapat membuat '%s'" msgid "cannot process '%s' and '%s' at the same time" msgstr "tidak dapat memproses '%s' dan '%s' pada waktu yang bersamaan" -#: refs/files-backend.c -#, c-format -msgid "could not remove reference %s" -msgstr "tidak dapat menghapus referensi %s" - -#: refs/files-backend.c refs/packed-backend.c +#: refs.c #, c-format msgid "could not delete reference %s: %s" msgstr "tidak dapat menghapus referensi %s: %s" -#: refs/files-backend.c refs/packed-backend.c +#: refs.c #, c-format msgid "could not delete references: %s" msgstr "tidak dapat menghapus referensi: %s" @@ -23981,9 +24250,9 @@ msgid "" msgstr "" "Tujuan yang Anda berikan bukan nama referensi penuh (seperti \n" "dimulai dengan \"refs/\"). Kami mencoba menebak maksud Anda dengan:\n" -"- Cari referensi yang cocok dengan '%s' pada sisi remote.\n" -"- Perika apakah <src> yang sedang didorong ('%s') adalah \n" -" referensi pada \"refs/{heads,tags}\". Bila demikian kami \n" +"- mencari referensi yang cocok dengan '%s' pada sisi remote.\n" +"- memeriksa apakah <src> yang sedang didorong ('%s') adalah \n" +" referensi pada \"refs/{heads,tags}/\". Bila demikian kami \n" " menambahkan awalan refs/{heads,tags}/ yang bersesuaian pada sisi \n" " remote.\n" "\n" @@ -24434,8 +24703,16 @@ msgid "only download metadata for the branch that will be checked out" msgstr "hanya unduh metadata untuk cabang yang akan dicheckout" #: scalar.c -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [<options>] [--] <repositori> [<direktori>]" +msgid "create repository within 'src' directory" +msgstr "salin repositori di dalam direktori 'src'" + +#: scalar.c +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <cabang utama>] [--full-clone]\n" +"\t[--[-no-]src] <url> [<pendaftaran>]" #: scalar.c #, c-format @@ -24501,13 +24778,32 @@ msgstr "tidak dapat menghapus scalar.repo basi '%s'" #: scalar.c #, c-format -msgid "removing stale scalar.repo '%s'" +msgid "removed stale scalar.repo '%s'" msgstr "menghapus scalar.repo basi '%s'" #: scalar.c #, c-format -msgid "git repository gone in '%s'" -msgstr "repositori git pergi di '%s'" +msgid "repository at '%s' has different owner" +msgstr "repositori pada '%s' berpemilik lain" + +#: scalar.c +#, c-format +msgid "repository at '%s' has a format issue" +msgstr "repositori pada '%s' ada masalah format" + +#: scalar.c +#, c-format +msgid "repository not found in '%s'" +msgstr "repositori tidak ditemukan di '%s'" + +#: scalar.c +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"untuk mencabut repositori ini dari Scalar, jalankan\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" #: scalar.c msgid "" @@ -24896,7 +25192,7 @@ msgstr "identitas pengarang tidak valid '%s'" msgid "corrupt author: missing date information" msgstr "pengarang rusak: informasi tanggal hilang" -#: sequencer.c t/helper/test-fast-rebase.c +#: sequencer.c #, c-format msgid "could not update %s" msgstr "tidak dapat memperbarui %s" @@ -24993,11 +25289,6 @@ msgstr "%s: tidak dapat menguraikan komit induk %s" #: sequencer.c #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "tidak dapat menamai ulang '%s' ke '%s'" - -#: sequencer.c -#, c-format msgid "could not revert %s... %s" msgstr "tidak dapat membalikkan %s... %s" @@ -25396,6 +25687,10 @@ msgid "Autostash exists; creating a new stash entry." msgstr "Stase otomatis sudah ada; membuat entri stase baru." #: sequencer.c +msgid "autostash reference is a symref" +msgstr "referensi autostase itu referensi simbolik" + +#: sequencer.c msgid "could not detach HEAD" msgstr "tidak dapat melepas HEAD" @@ -25432,13 +25727,13 @@ msgstr "" #: sequencer.c #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "Mendasarkan ulang (%d/%d)%s" +msgid "Stopped at %s... %.*s\n" +msgstr "Berhenti pada %s... %.*s\n" #: sequencer.c #, c-format -msgid "Stopped at %s... %.*s\n" -msgstr "Berhenti pada %s... %.*s\n" +msgid "Rebasing (%d/%d)%s" +msgstr "Mendasarkan ulang (%d/%d)%s" #: sequencer.c #, c-format @@ -25777,6 +26072,11 @@ msgstr "nama cabang asal salah: '%s'" #: setup.c #, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "re-init: --initial-branch=%s diabaikan" + +#: setup.c +#, c-format msgid "unable to handle file type %d" msgstr "tidak dapat menangani tipe berkas %d" @@ -25790,14 +26090,16 @@ msgid "attempt to reinitialize repository with different hash" msgstr "mencoba menginisialisasi ulang repositori dengan hash yang berbeda" #: setup.c -#, c-format -msgid "%s already exists" -msgstr "%s sudah ada" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "" +"mencoba menginisialisasi ulang repositori dengan format penyimpanan " +"referensi yang berbeda" #: setup.c #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "re-init: --initial-branch=%s diabaikan" +msgid "%s already exists" +msgstr "%s sudah ada" #: setup.c #, c-format @@ -26123,14 +26425,6 @@ msgstr "bersihkan pohon tembolok sebelum setiap iterasi" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "jumlah entri di dalam pohon tembolok untuk dinirvalidasi (asali 0)" -#: t/helper/test-fast-rebase.c -msgid "unhandled options" -msgstr "opsi tak tertangani" - -#: t/helper/test-fast-rebase.c -msgid "error preparing revisions" -msgstr "kesalahan menyiapkan revisi" - #: t/helper/test-reach.c #, c-format msgid "commit %s is not marked reachable" @@ -26328,10 +26622,6 @@ msgstr "menyetel jalur layanan remote tidak didukung oleh protokol" msgid "invalid remote service path" msgstr "jalur layanan remote tidak valid" -#: transport-helper.c transport.c -msgid "operation not supported by protocol" -msgstr "operasi tidak didukung oleh protokol" - #: transport-helper.c #, c-format msgid "can't connect to subservice %s" @@ -26497,11 +26787,6 @@ msgstr "dukungan untuk protokol v2 belum diterapkan" #: transport.c #, c-format -msgid "unknown value for config '%s': %s" -msgstr "nilai tidak dikenal untuk konfigurasi '%s': %s" - -#: transport.c -#, c-format msgid "transport '%s' not allowed" msgstr "transportasi '%s' tidak diperbolehkan" @@ -26560,6 +26845,10 @@ msgstr "operasi bundle-uri tidak didukung oleh protokol" msgid "could not retrieve server-advertised bundle-uri list" msgstr "tidak dapat menerima daftar bundle-uri teriklankan server" +#: transport.c +msgid "operation not supported by protocol" +msgstr "operasi tidak didukung oleh protokol" + #: tree-walk.c msgid "too-short tree object" msgstr "objek pohon terlalu pendek" @@ -27020,6 +27309,10 @@ msgstr "tidak dapat mengakses '%s'" msgid "unable to get current working directory" msgstr "tidak dapat mendapatkan direktori kerja saat ini" +#: wrapper.c +msgid "unable to get random bytes" +msgstr "tidak dapat mendapatkan bita acak" + #: wt-status.c msgid "Unmerged paths:" msgstr "Jalur yang tak tergabung:" @@ -27577,6 +27870,11 @@ msgstr "juga indeks Anda berisi perubahan yang belum dikomit." msgid "cannot %s: Your index contains uncommitted changes." msgstr "tidak dapat %s: indeks Anda berisi perubahan yang belum dikomit." +#: xdiff-interface.c +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "nilai gaya tidak dikenal '%s' diberikan untuk '%s'" + #: git-merge-octopus.sh git-merge-resolve.sh msgid "" "Error: Your local changes to the following files would be overwritten by " @@ -27799,13 +28097,13 @@ msgstr "" #: git-send-email.perl #, perl-format -msgid "Failed to open %s: %s" -msgstr "Gagal membuka %s: %s" +msgid "Failed to open %s.final: %s" +msgstr "Gagal membuka %s.final: %s" #: git-send-email.perl #, perl-format -msgid "Failed to open %s.final: %s" -msgstr "Gagal membuka %s.final: %s" +msgid "Failed to open %s: %s" +msgstr "Gagal membuka %s: %s" #: git-send-email.perl msgid "Summary email is empty, skipping it\n" @@ -28046,22 +28344,3 @@ msgstr "Melewati %s dengan akhiran cadangan '%s'.\n" #, perl-format msgid "Do you really want to send %s? [y|N]: " msgstr "Anda benar-benar ingin mengirim %s? [y|N]: " - -#~ msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" -#~ msgstr "" -#~ "jangan lewatkan opsi --keep-cr ke git-mailsplit tak bergantung pada am." -#~ "keepcr" - -#~ 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 "" -#~ "Pembaruan ditolak karena ujung dari cabang pelacak remote\n" -#~ "sudah diperbarui sejak checkout terakhir. Mungkin Anda ingin\n" -#~ "integrasikan perubahan tersebut ke lokal (seperti 'git pull...')\n" -#~ "sebelum memaksa pembaruan.\n" - -#~ msgid "or do not fetch any tag at all (--no-tags)" -#~ msgstr "atau jangan mengambil tag apapun (--no-tags)" @@ -1,14 +1,14 @@ # Swedish translations for Git. -# Copyright (C) 2010-2023 Peter Krefting <peter@softwolves.pp.se> +# Copyright (C) 2010-2024 Peter Krefting <peter@softwolves.pp.se> # This file is distributed under the same license as the Git package. -# Peter Krefting <peter@softwolves.pp.se>, 2010-2023. +# Peter Krefting <peter@softwolves.pp.se>, 2010-2024. # msgid "" msgstr "" -"Project-Id-Version: git 2.42.0\n" +"Project-Id-Version: git 2.44.0\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-16 07:40+0100\n" -"PO-Revision-Date: 2023-08-16 07:42+0100\n" +"POT-Creation-Date: 2024-02-16 07:58+0100\n" +"PO-Revision-Date: 2024-02-16 07:59+0100\n" "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n" "Language-Team: Svenska <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Gtranslator 3.38.0\n" +"X-Generator: Gtranslator 42.0\n" #, c-format msgid "Huh (%s)?" @@ -39,7 +39,7 @@ msgstr "Uppdatera" #, c-format msgid "could not stage '%s'" -msgstr "kunde inte köa \"%s\"" +msgstr "kunde inte köa â€%sâ€" msgid "could not write index" msgstr "kunde inte skriva indexet" @@ -56,7 +56,7 @@ msgstr "observera: %s spÃ¥ras inte längre.\n" #, c-format msgid "make_cache_entry failed for path '%s'" -msgstr "make_cache_entry misslyckades för sökvägen \"%s\"" +msgstr "make_cache_entry misslyckades för sökvägen â€%sâ€" msgid "Revert" msgstr "Ã…terställ" @@ -228,7 +228,7 @@ msgid "" "stashing." msgstr "" "Om patchen kan appliceras rent kommer det redigerade stycket att läggas till " -"i \"stash\" omedelbart." +"i â€stash†omedelbart." msgid "" "y - stash this hunk\n" @@ -237,11 +237,11 @@ msgid "" "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 "" -"y - \"stash\":a stycket\n" -"n - \"stash\":a inte stycket\n" -"q - avsluta; \"stash\":a inte stycket eller nÃ¥got av de följande\n" -"a - \"stash\":a stycket och alla följande i filen\n" -"d - \"stash\":a inte stycket eller nÃ¥got av de följande i filen\n" +"y - â€stashâ€:a stycket\n" +"n - â€stashâ€:a inte stycket\n" +"q - avsluta; â€stashâ€:a inte stycket eller nÃ¥got av de följande\n" +"a - â€stashâ€:a stycket och alla följande i filen\n" +"d - â€stashâ€:a inte stycket eller nÃ¥got av de följande i filen\n" #, c-format msgid "Unstage mode change [y,n,q,a,d%s,?]? " @@ -440,7 +440,7 @@ msgstr "" #, c-format msgid "could not parse hunk header '%.*s'" -msgstr "kunde inte tolka styckehuvudet \"%.*s\"" +msgstr "kunde inte tolka styckehuvudet â€%.*sâ€" msgid "could not parse diff" msgstr "kunde inte tolka diff" @@ -450,7 +450,7 @@ msgstr "kunde inte tolka färgad diff" #, c-format msgid "failed to run '%s'" -msgstr "misslyckades att köra \"%s\"" +msgstr "misslyckades att köra â€%sâ€" msgid "mismatched output from interactive.diffFilter" msgstr "omaka utdata frÃ¥n interactive.diffFilter" @@ -493,8 +493,8 @@ msgid "" "Lines starting with %c will be removed.\n" msgstr "" "---\n" -"Ta bort \"%c\" rader genom att göra dem \" \"-rader (sammanhang).\n" -"Ta bort \"%c\" rader genom att radera dem.\n" +"Ta bort â€%c†rader genom att göra dem †â€-rader (sammanhang).\n" +"Ta bort â€%c†rader genom att radera dem.\n" "Rader som börjar med %c kommer att tas bort.\n" msgid "" @@ -510,7 +510,7 @@ msgid "could not parse hunk header" msgstr "kunde inte tolka styckehuvud" msgid "'git apply --cached' failed" -msgstr "\"git apply --cached\" misslyckades" +msgstr "â€git apply --cached†misslyckades" #. TRANSLATORS: do not translate [y/n] #. The program will only accept that input at this point. @@ -521,8 +521,8 @@ msgstr "\"git apply --cached\" misslyckades" msgid "" "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? " msgstr "" -"Ditt redigerade stycke kan inte appliceras. Redigera igen (\"nej\" kastar!) " -"[y/n]? " +"Ditt redigerade stycke kan inte appliceras. Redigera igen (â€nej†kastar!) [y/" +"n]? " msgid "The selected hunks do not apply to the index!" msgstr "Markerade stycken kan inte appliceras pÃ¥ indexet!" @@ -571,7 +571,7 @@ msgstr "gÃ¥ till vilket stycke? " #, c-format msgid "Invalid number: '%s'" -msgstr "Ogiltigt siffervärde: \"%s\"" +msgstr "Ogiltigt siffervärde: â€%sâ€" #, c-format msgid "Sorry, only %d hunk available." @@ -603,7 +603,7 @@ msgid "Sorry, cannot edit this hunk" msgstr "Beklagar, kan inte redigera stycket" msgid "'git apply' failed" -msgstr "\"git apply\" misslyckades" +msgstr "â€git apply†misslyckades" #, c-format msgid "" @@ -611,7 +611,7 @@ msgid "" "Disable this message with \"git config advice.%s false\"" msgstr "" "\n" -"SlÃ¥ av meddelandet med \"git config advice.%s false\"" +"SlÃ¥ av meddelandet med â€git config advice.%s falseâ€" #, c-format msgid "%shint: %.*s%s\n" @@ -619,7 +619,7 @@ msgstr "%stips: %.*s%s\n" msgid "Cherry-picking is not possible because you have unmerged files." msgstr "" -"Du kan inte utföra en \"cherry-pick\" eftersom du har filer som inte slagits " +"Du kan inte utföra en â€cherry-pick†eftersom du har filer som inte slagits " "samman." msgid "Committing is not possible because you have unmerged files." @@ -632,7 +632,7 @@ msgstr "" msgid "Pulling is not possible because you have unmerged files." msgstr "" -"Du kan inte utföra en \"pull\" eftersom du har filer som inte slagits samman." +"Du kan inte utföra en â€pull†eftersom du har filer som inte slagits samman." msgid "Reverting is not possible because you have unmerged files." msgstr "Du kan inte Ã¥terställa eftersom du har filer som inte slagits samman." @@ -644,7 +644,7 @@ msgid "" "Fix them up in the work tree, and then use 'git add/rm <file>'\n" "as appropriate to mark resolution and make a commit." msgstr "" -"Rätta dem i din arbetskatalog och använd sedan \"git add/rm <fil>\"\n" +"Rätta dem i din arbetskatalog och använd sedan â€git add/rm <fil>â€\n" "som lämpligt för att ange lösning och checka in." msgid "Exiting because of an unresolved conflict." @@ -686,7 +686,7 @@ msgid "" "updated in the index:\n" msgstr "" "Följande sökvägar och/eller sökvägsangivelser motsvarar sökvägar\n" -"utanför din \"sparse-checkout\"-definition, sÃ¥ de kommer inte\n" +"utanför din â€sparse-checkoutâ€-definition, sÃ¥ de kommer inte\n" "uppdateras i indexet:\n" msgid "" @@ -719,9 +719,9 @@ msgid "" "false\n" "\n" msgstr "" -"Observera: checkar ut \"%s\".\n" +"Observera: checkar ut â€%sâ€.\n" "\n" -"Du har nu ett \"frÃ¥nkopplat HEAD\". Du kan se dig omkring, experimentera\n" +"Du har nu ett â€frÃ¥nkopplat HEADâ€. Du kan se dig omkring, experimentera\n" "med ändringar och checka in dem, och du kan kasta incheckningar du gör\n" "i det här läget utan att det pÃ¥verkar grenar genom att växla tillbaka\n" "till en gren.\n" @@ -747,7 +747,7 @@ msgid "" "modifications.\n" msgstr "" "Följande sökvägar har flyttats ut frÃ¥n din\n" -"\"sparse-checkout\"-definition, men är inte glesa pÃ¥ grund av\n" +"â€sparse-checkoutâ€-definition, men är inte glesa pÃ¥ grund av\n" "lokala ändringar.\n" msgid "" @@ -756,8 +756,8 @@ msgid "" "* Use \"git sparse-checkout reapply\" to apply the sparsity rules" msgstr "" "För att korrigera glesheten för dessa sökvägar, gör följande:\n" -"* Använd \"git add --sparse <sökväg>\" för att uppdatera indexet\n" -"* Använd \"git sparse-checkout reapply\" för att tillämpa gleshetsreglerna" +"* Använd â€git add --sparse <sökväg>†för att uppdatera indexet\n" +"* Använd â€git sparse-checkout reapply†för att tillämpa gleshetsreglerna" msgid "cmdline ends with \\" msgstr "kommandorad avslutas med \\" @@ -770,19 +770,19 @@ msgstr "för mÃ¥nga argument" #, c-format msgid "unrecognized whitespace option '%s'" -msgstr "okänt alternativ för whitespace: \"%s\"" +msgstr "okänt alternativ för whitespace: â€%sâ€" #, c-format msgid "unrecognized whitespace ignore option '%s'" -msgstr "okänt alternativ för ignore-whitespace: \"%s\"" +msgstr "okänt alternativ för ignore-whitespace: â€%sâ€" #, c-format msgid "options '%s' and '%s' cannot be used together" -msgstr "flaggorna \"%s\" och \"%s\" kan inte användas samtidigt" +msgstr "flaggorna â€%s†och â€%s†kan inte användas samtidigt" #, c-format msgid "'%s' outside a repository" -msgstr "\"%s\" utanför arkiv" +msgstr "â€%s†utanför arkiv" msgid "failed to read patch" msgstr "misslyckades läsa patchen" @@ -897,7 +897,7 @@ msgstr "kunde inte öppna eller läsa %s" #, c-format msgid "invalid start of line: '%c'" -msgstr "felaktig inledning pÃ¥ rad: \"%c\"" +msgstr "felaktig inledning pÃ¥ rad: â€%câ€" #, c-format msgid "Hunk #%d succeeded at %d (offset %d line)." @@ -919,41 +919,38 @@ msgstr "" #, c-format msgid "missing binary patch data for '%s'" -msgstr "saknar binära patchdata för \"%s\"" +msgstr "saknar binära patchdata för â€%sâ€" #, c-format msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'" msgstr "" -"kan inte applicera en binärpatch baklänges utan den omvända patchen för \"%s" -"\"" +"kan inte applicera en binärpatch baklänges utan den omvända patchen för â€%sâ€" #, c-format msgid "cannot apply binary patch to '%s' without full index line" -msgstr "" -"kan inte applicera binärpatch pÃ¥ \"%s\" utan den fullständiga indexraden" +msgstr "kan inte applicera binärpatch pÃ¥ â€%s†utan den fullständiga indexraden" #, c-format msgid "" "the patch applies to '%s' (%s), which does not match the current contents." msgstr "" -"patchen appliceras pÃ¥ \"%s\" (%s), som inte motsvarar det nuvarande " -"innehÃ¥llet." +"patchen appliceras pÃ¥ â€%s†(%s), som inte motsvarar det nuvarande innehÃ¥llet." #, c-format msgid "the patch applies to an empty '%s' but it is not empty" -msgstr "patchen appliceras pÃ¥ en tom \"%s\", men den är inte tom" +msgstr "patchen appliceras pÃ¥ en tom â€%sâ€, men den är inte tom" #, c-format msgid "the necessary postimage %s for '%s' cannot be read" -msgstr "nödvändig efterbild %s för \"%s\" kan inte läsas" +msgstr "nödvändig efterbild %s för â€%s†kan inte läsas" #, c-format msgid "binary patch does not apply to '%s'" -msgstr "binärpatchen kan inte tillämpas pÃ¥ \"%s\"" +msgstr "binärpatchen kan inte tillämpas pÃ¥ â€%sâ€" #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" -msgstr "binärpatchen pÃ¥ \"%s\" ger felaktigt resultat (förväntade %s, fick %s)" +msgstr "binärpatchen pÃ¥ â€%s†ger felaktigt resultat (förväntade %s, fick %s)" #, c-format msgid "patch failed: %s:%ld" @@ -969,7 +966,7 @@ msgstr "misslyckades läsa %s" #, c-format msgid "reading from '%s' beyond a symbolic link" -msgstr "läser frÃ¥n \"%s\" som är pÃ¥ andra sidan av en symbolisk länk" +msgstr "läser frÃ¥n â€%s†som är pÃ¥ andra sidan av en symbolisk länk" #, c-format msgid "path %s has been renamed/deleted" @@ -992,7 +989,7 @@ msgstr "Utför trevägssammanslagning...\n" #, c-format msgid "cannot read the current contents of '%s'" -msgstr "kunde inte läsa aktuellt innehÃ¥ll i \"%s\"" +msgstr "kunde inte läsa aktuellt innehÃ¥ll i â€%sâ€" #, c-format msgid "Failed to perform three-way merge...\n" @@ -1000,11 +997,11 @@ msgstr "Misslyckades utföra trevägssammanslagning...\n" #, c-format msgid "Applied patch to '%s' with conflicts.\n" -msgstr "Applicerade patchen pÃ¥ \"%s\" med konflikter.\n" +msgstr "Applicerade patchen pÃ¥ â€%s†med konflikter.\n" #, c-format msgid "Applied patch to '%s' cleanly.\n" -msgstr "Tillämpade patchen pÃ¥ \"%s\" rent.\n" +msgstr "Tillämpade patchen pÃ¥ â€%s†rent.\n" #, c-format msgid "Falling back to direct application...\n" @@ -1023,7 +1020,7 @@ msgstr "%s har typen %o, förväntade %o" #, c-format msgid "invalid path '%s'" -msgstr "ogiltig sökväg \"%s\"" +msgstr "ogiltig sökväg â€%sâ€" #, c-format msgid "%s: already exists in index" @@ -1043,7 +1040,7 @@ msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o) för %s" #, c-format msgid "affected file '%s' is beyond a symbolic link" -msgstr "den berörda filen \"%s\" är pÃ¥ andra sidan av en symbolisk länk" +msgstr "den berörda filen â€%s†är pÃ¥ andra sidan av en symbolisk länk" #, c-format msgid "%s: patch does not apply" @@ -1083,7 +1080,7 @@ msgstr "trasig patch för undermodulen %s" #, c-format msgid "unable to stat newly created file '%s'" -msgstr "kan inte ta status pÃ¥ nyligen skapade filen \"%s\"" +msgstr "kan inte ta status pÃ¥ nyligen skapade filen â€%sâ€" #, c-format msgid "unable to create backing store for newly created file %s" @@ -1095,15 +1092,15 @@ msgstr "kan inte lägga till cachepost för %s" #, c-format msgid "failed to write to '%s'" -msgstr "misslyckades skriva till \"%s\"" +msgstr "misslyckades skriva till â€%sâ€" #, c-format msgid "closing file '%s'" -msgstr "stänger filen \"%s\"" +msgstr "stänger filen â€%sâ€" #, c-format msgid "unable to write file '%s' mode %o" -msgstr "kan inte skriva filen \"%s\" läge %o" +msgstr "kan inte skriva filen â€%s†läge %o" #, c-format msgid "Applied patch %s cleanly." @@ -1128,7 +1125,7 @@ msgstr "kan inte öppna %s" #, c-format msgid "cannot unlink '%s'" -msgstr "kan inte ta bort länken \"%s\"" +msgstr "kan inte ta bort länken â€%sâ€" #, c-format msgid "Hunk #%d applied cleanly." @@ -1140,17 +1137,17 @@ msgstr "Refuserar stycke %d." #, c-format msgid "Skipped patch '%s'." -msgstr "Ignorerar patch \"%s\"." +msgstr "Ignorerar patch â€%sâ€." msgid "No valid patches in input (allow with \"--allow-empty\")" -msgstr "Inga giltiga patchar i indata (tillÃ¥t med \"--allow-empty\")" +msgstr "Inga giltiga patchar i indata (tillÃ¥t med â€--allow-emptyâ€)" msgid "unable to read index file" msgstr "kan inte läsa indexfilen" #, c-format msgid "can't open patch '%s': %s" -msgstr "kan inte öppna patchen \"%s\": %s" +msgstr "kan inte öppna patchen â€%sâ€: %s" #, c-format msgid "squelched %d whitespace error" @@ -1204,7 +1201,7 @@ msgid "make sure the patch is applicable to the current index" msgstr "se till att patchen kan tillämpas pÃ¥ aktuellt index" msgid "mark new files with `git add --intent-to-add`" -msgstr "markera nya filer med \"git add --intent-to-add\"" +msgstr "markera nya filer med â€git add --intent-to-addâ€" msgid "apply a patch without touching the working tree" msgstr "tillämpa en patch utan att röra arbetskatalogen" @@ -1279,14 +1276,14 @@ msgstr "fel i deflate (%d)" #, c-format msgid "unable to start '%s' filter" -msgstr "kunde inte starta filtret \"%s\"" +msgstr "kunde inte starta filtret â€%sâ€" msgid "unable to redirect descriptor" msgstr "kan inte omdirigera handtag" #, c-format msgid "'%s' filter reported error" -msgstr "filtret \"%s\" rapporterade fel" +msgstr "filtret â€%s†rapporterade fel" #, c-format msgid "path is not valid UTF-8: %s" @@ -1314,15 +1311,15 @@ msgstr "git archive --remote <arkiv> [--exec <kmd>] --list" #, c-format msgid "cannot read '%s'" -msgstr "kunde inte läsa \"%s\"" +msgstr "kunde inte läsa â€%sâ€" #, c-format msgid "pathspec '%s' matches files outside the current directory" -msgstr "sökvägsangivelsen \"%s\" motsvarar filer utanför aktuell katalog" +msgstr "sökvägsangivelsen â€%s†motsvarar filer utanför aktuell katalog" #, c-format msgid "pathspec '%s' did not match any files" -msgstr "sökvägsangivelsen \"%s\" motsvarade inte nÃ¥gra filer" +msgstr "sökvägsangivelsen â€%s†motsvarade inte nÃ¥gra filer" #, c-format msgid "no such ref: %.*s" @@ -1346,15 +1343,15 @@ msgstr "Inte en vanlig fil: %s" #, c-format msgid "unclosed quote: '%s'" -msgstr "citat ej stängt: \"%s\"" +msgstr "citat ej stängt: â€%sâ€" #, c-format msgid "missing colon: '%s'" -msgstr "kolon saknas: \"%s\"" +msgstr "kolon saknas: â€%sâ€" #, c-format msgid "empty file name: '%s'" -msgstr "tomt filnamn: \"%s\"" +msgstr "tomt filnamn: â€%sâ€" msgid "fmt" msgstr "fmt" @@ -1415,18 +1412,22 @@ msgstr "Oväntad flagga --remote" #, c-format msgid "the option '%s' requires '%s'" -msgstr "flaggan \"%s\" kräver \"%s\"" +msgstr "flaggan â€%s†kräver â€%sâ€" msgid "Unexpected option --output" msgstr "Oväntad flagga --output" #, c-format +msgid "extra command line parameter '%s'" +msgstr "falsk konfigureringsparameter: â€%sâ€" + +#, c-format msgid "Unknown archive format '%s'" -msgstr "Okänt arkivformat \"%s\"" +msgstr "Okänt arkivformat â€%sâ€" #, c-format msgid "Argument not supported for format '%s': -%d" -msgstr "Argumentet stöd inte för formatet \"%s\": -%d" +msgstr "Argumentet stöd inte för formatet â€%sâ€: -%d" #, c-format msgid "%.*s is not a valid attribute name" @@ -1452,26 +1453,34 @@ msgstr "" #, c-format msgid "cannot fstat gitattributes file '%s'" -msgstr "kan inte utföra fstat pÃ¥ gitattributes-filen \"%s\"" +msgstr "kan inte utföra fstat pÃ¥ gitattributes-filen â€%sâ€" #, c-format msgid "ignoring overly large gitattributes file '%s'" -msgstr "ignorerar allt för stor gitattributes-fil \"%s\"" +msgstr "ignorerar allt för stor gitattributes-fil â€%sâ€" #, c-format msgid "ignoring overly large gitattributes blob '%s'" -msgstr "ignorerar allt för stor gitattributes-objekt \"%s\"" +msgstr "ignorerar allt för stor gitattributes-objekt â€%sâ€" msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "felaktig --attr-source eller GIT_ATTR_SOURCE" #, c-format +msgid "unable to stat '%s'" +msgstr "kan inte ta status pÃ¥ â€%sâ€" + +#, c-format +msgid "unable to read %s" +msgstr "kunde inte läsa %s" + +#, c-format msgid "Badly quoted content in file '%s': %s" -msgstr "Felaktigt citerat innehÃ¥ll i filen \"%s\": %s" +msgstr "Felaktigt citerat innehÃ¥ll i filen â€%sâ€: %s" #, c-format msgid "We cannot bisect more!\n" -msgstr "Det finns inte mer att göra \"bisect\" pÃ¥!\n" +msgstr "Det finns inte mer att göra â€bisect†pÃ¥!\n" #, c-format msgid "Not a valid commit name %s" @@ -1499,7 +1508,7 @@ msgid "" "This means the first '%s' commit is between %s and [%s].\n" msgstr "" "Sammanslagningsbasen %s är %s.\n" -"Det betyder att den första \"%s\" incheckningen är mellan %s och [%s].\n" +"Det betyder att den första â€%s†incheckningen är mellan %s och [%s].\n" #, c-format msgid "" @@ -1532,11 +1541,11 @@ msgstr "en %s-revision behövs" #, c-format msgid "could not create file '%s'" -msgstr "kunde inte skapa filen \"%s\"" +msgstr "kunde inte skapa filen â€%sâ€" #, c-format msgid "could not read file '%s'" -msgstr "kunde inte läsa filen \"%s\"" +msgstr "kunde inte läsa filen â€%sâ€" msgid "reading bisect refs failed" msgstr "misslyckades läsa bisect-referenser" @@ -1606,15 +1615,15 @@ msgstr "ställer inte in grenen %s som sin egen uppströmsgren" #, c-format msgid "branch '%s' set up to track '%s' by rebasing." -msgstr "grenen \"%s\" inställd pÃ¥ att spÃ¥ra \"%s\" genom ombasering." +msgstr "grenen â€%s†inställd pÃ¥ att spÃ¥ra â€%s†genom ombasering." #, c-format msgid "branch '%s' set up to track '%s'." -msgstr "grenen \"%s\" inställd pÃ¥ att spÃ¥ra \"%s\"." +msgstr "grenen â€%s†inställd pÃ¥ att spÃ¥ra â€%sâ€." #, c-format msgid "branch '%s' set up to track:" -msgstr "grenen \"%s\" inställd pÃ¥ att spÃ¥ra:" +msgstr "grenen â€%s†inställd pÃ¥ att spÃ¥ra:" msgid "unable to write upstream branch configuration" msgstr "kan inte skriva inställningar för uppströmsgren" @@ -1630,17 +1639,17 @@ msgstr "" #, c-format msgid "asked to inherit tracking from '%s', but no remote is set" -msgstr "bad om att ärva spÃ¥rning frÃ¥n \"%s\", men ingen fjärr är vald" +msgstr "bad om att ärva spÃ¥rning frÃ¥n â€%sâ€, men ingen fjärr är vald" #, c-format msgid "asked to inherit tracking from '%s', but no merge configuration is set" msgstr "" -"bad om att ärva spÃ¥rning frÃ¥n \"%s\", men ingen sammanslagningsinställning " -"är vald" +"bad om att ärva spÃ¥rning frÃ¥n â€%sâ€, men ingen sammanslagningsinställning är " +"vald" #, c-format msgid "not tracking: ambiguous information for ref '%s'" -msgstr "spÃ¥rar inte: tvetydig information för referensen \"%s\"" +msgstr "spÃ¥rar inte: tvetydig information för referensen â€%sâ€" #. #-#-#-#-# branch.c.po #-#-#-#-# #. TRANSLATORS: This is a line listing a remote with duplicate @@ -1672,7 +1681,7 @@ msgid "" "tracking namespaces." msgstr "" "Flera fjärrars hämtnings-referensspecifikationer motsvarar fjärr-\n" -"spÃ¥rningsreferensen \"%s\":\n" +"spÃ¥rningsreferensen â€%sâ€:\n" "%s\n" "Detta är vanligtvis ett fel i konfigurationen.\n" "\n" @@ -1682,26 +1691,26 @@ msgstr "" #, c-format msgid "'%s' is not a valid branch name" -msgstr "\"%s\" är inte ett giltigt grennamn" +msgstr "â€%s†är inte ett giltigt grennamn" #, c-format msgid "a branch named '%s' already exists" -msgstr "det finns redan en gren som heter \"%s\"" +msgstr "det finns redan en gren som heter â€%sâ€" #, c-format msgid "cannot force update the branch '%s' used by worktree at '%s'" msgstr "" -"kan inte tvinga uppdatering av grenen \"%s\" som används av arbetskatalogen " -"pÃ¥ \"%s\"" +"kan inte tvinga uppdatering av grenen â€%s†som används av arbetskatalogen pÃ¥ " +"â€%sâ€" #, c-format msgid "cannot set up tracking information; starting point '%s' is not a branch" msgstr "" -"kan inte ställa in spÃ¥rningsinformation; startpunkten \"%s\" är inte en gren" +"kan inte ställa in spÃ¥rningsinformation; startpunkten â€%s†är inte en gren" #, c-format msgid "the requested upstream branch '%s' does not exist" -msgstr "den efterfrÃ¥gade uppströmsgrenen \"%s\" finns inte" +msgstr "den efterfrÃ¥gade uppströmsgrenen â€%s†finns inte" msgid "" "\n" @@ -1715,51 +1724,51 @@ msgid "" msgstr "" "\n" "Om du har tänkt basera ditt arbete pÃ¥ en uppströmsgren\n" -"som redan finns pÃ¥ fjärren kan du behöva köra \"git fetch\"\n" +"som redan finns pÃ¥ fjärren kan du behöva köra â€git fetchâ€\n" "för att hämta den.\n" "\n" "Om du har tänkt sända in en ny lokal gren som ska\n" -"spÃ¥ra dess fjärrmotsvarighet kan du använda \"git push -u\"\n" +"spÃ¥ra dess fjärrmotsvarighet kan du använda â€git push -uâ€\n" "för att ställa in uppströmskonfigurationen när du sänder in." #, c-format msgid "not a valid object name: '%s'" -msgstr "objektnamnet är inte giltigt: \"%s\"" +msgstr "objektnamnet är inte giltigt: â€%sâ€" #, c-format msgid "ambiguous object name: '%s'" -msgstr "objektnamnet är tvetydigt: \"%s\"" +msgstr "objektnamnet är tvetydigt: â€%sâ€" #, c-format msgid "not a valid branch point: '%s'" -msgstr "avgreningspunkten är inte giltig: \"%s\"" +msgstr "avgreningspunkten är inte giltig: â€%sâ€" #, c-format msgid "submodule '%s': unable to find submodule" -msgstr "undermodulen \"%s\": kan inte hitta undermodulen" +msgstr "undermodulen â€%sâ€: kan inte hitta undermodulen" #, c-format msgid "" "You may try updating the submodules using 'git checkout --no-recurse-" "submodules %s && git submodule update --init'" msgstr "" -"Du kan försöka uppdatera undermodulerna med \"git checkout --no-recurse-" -"submodules %s && git submodule update --init\"" +"Du kan försöka uppdatera undermodulerna med â€git checkout --no-recurse-" +"submodules %s && git submodule update --initâ€" #, c-format msgid "submodule '%s': cannot create branch '%s'" -msgstr "undermodulen \"%s\": kan inte skapa grenen \"%s\"" +msgstr "undermodulen â€%sâ€: kan inte skapa grenen â€%sâ€" #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "\"%s\" är redan utcheckad pÃ¥ \"%s\"" +msgid "'%s' is already used by worktree at '%s'" +msgstr "â€%s†används redan av arbetskatalogen â€%sâ€" msgid "git add [<options>] [--] <pathspec>..." msgstr "git add [<flaggor>] [--] <sökväg>..." #, c-format msgid "cannot chmod %cx '%s'" -msgstr "kan inte utföra chmod %cx \"%s\"" +msgstr "kan inte utföra chmod %cx â€%sâ€" msgid "Unstaged changes after refreshing the index:" msgstr "Oköade ändringar efter att ha uppdaterat indexet:" @@ -1769,27 +1778,24 @@ msgid "" "See its entry in 'git help config' for details." msgstr "" "inställningen add.interactive.useBuiltin har tagits bort!\n" -"Se dess post i \"git help config\" för detaljer." - -msgid "Could not read the index" -msgstr "Kunde inte läsa indexet" +"Se dess post i â€git help config†för detaljer." -msgid "Could not write patch" -msgstr "Kunde inte skriva patch" +msgid "could not read the index" +msgstr "kunde inte läsa indexet" msgid "editing patch failed" msgstr "redigering av patch misslyckades" #, c-format -msgid "Could not stat '%s'" -msgstr "Kunde inte ta status pÃ¥ \"%s\"" +msgid "could not stat '%s'" +msgstr "kunde inte ta status pÃ¥ â€%sâ€" -msgid "Empty patch. Aborted." -msgstr "Tom patch. Avbryter." +msgid "empty patch. aborted" +msgstr "tom patch. avbryter" #, c-format -msgid "Could not apply '%s'" -msgstr "Kunde inte tillämpa \"%s\"" +msgid "could not apply '%s'" +msgstr "kunde inte tillämpa â€%sâ€" msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "Följande sökvägar ignoreras av en av dina .gitignore-filer:\n" @@ -1837,7 +1843,7 @@ msgid "check if - even missing - files are ignored in dry run" msgstr "se om - även saknade - filer ignoreras i testkörning" msgid "allow updating entries outside of the sparse-checkout cone" -msgstr "tillÃ¥t uppdatera poster utanför omrÃ¥det angivet i \"sparse-checkout\"" +msgstr "tillÃ¥t uppdatera poster utanför omrÃ¥det angivet i â€sparse-checkoutâ€" msgid "override the executable bit of the listed files" msgstr "överstyr exekveringsbiten för angivna filer" @@ -1873,7 +1879,7 @@ msgstr "" "\n" "\tgit rm --cached %s\n" "\n" -"Se \"git help submodule\" för ytterligare information." +"Se â€git help submodule†för ytterligare information." #, c-format msgid "adding embedded git repository: %s" @@ -1886,18 +1892,18 @@ msgid "" msgstr "" "Använd -f om du verkligen vill lägga till dem.\n" "SlÃ¥ av detta meddelande med\n" -"\"git config advice.addIgnoredFile false\"" +"â€git config advice.addIgnoredFile falseâ€" msgid "adding files failed" msgstr "misslyckades lägga till filer" #, c-format msgid "--chmod param '%s' must be either -x or +x" -msgstr "\"--chmod\"-parametern \"%s\" mÃ¥ste antingen vara -x eller +x" +msgstr "â€--chmodâ€-parametern â€%s†mÃ¥ste antingen vara -x eller +x" #, c-format msgid "'%s' and pathspec arguments cannot be used together" -msgstr "\"%s\" kan inte användas tillsammans med sökvägsangivelser" +msgstr "â€%s†kan inte användas tillsammans med sökvägsangivelser" #, c-format msgid "Nothing specified, nothing added.\n" @@ -1908,24 +1914,27 @@ msgid "" "Turn this message off by running\n" "\"git config advice.addEmptyPathspec false\"" msgstr "" -"Tänkte du kanske säga \"git add .\"?\n" +"Tänkte du kanske säga â€git add .â€?\n" "SlÃ¥ av detta meddelande genom att köra\n" -"\"git config advice.addEmptyPathspec false\"" +"â€git config advice.addEmptyPathspec falseâ€" msgid "index file corrupt" msgstr "indexfilen trasig" +msgid "unable to write new index file" +msgstr "kunde inte skriva ny indexfil" + #, c-format msgid "bad action '%s' for '%s'" -msgstr "felaktig funktion \"%s\" för \"%s\"" +msgstr "felaktig funktion â€%s†för â€%sâ€" #, c-format msgid "invalid value for '%s': '%s'" -msgstr "felaktigt värde för \"%s\": \"%s\"" +msgstr "felaktigt värde för â€%sâ€: â€%sâ€" #, c-format msgid "could not read '%s'" -msgstr "kunde inte läsa \"%s\"" +msgstr "kunde inte läsa â€%sâ€" msgid "could not parse author script" msgstr "kunde inte tolka författarskript" @@ -1936,30 +1945,30 @@ msgstr "kunde inte tolka %s" #, c-format msgid "'%s' was deleted by the applypatch-msg hook" -msgstr "\"%s\" togs bort av kroken applypatch-msg" +msgstr "â€%s†togs bort av kroken applypatch-msg" #, c-format msgid "Malformed input line: '%s'." -msgstr "Felaktig indatarad: \"%s\"." +msgstr "Felaktig indatarad: â€%sâ€." #, c-format msgid "Failed to copy notes from '%s' to '%s'" -msgstr "Misslyckades kopiera anteckningar frÃ¥n \"%s\" till \"%s\"" +msgstr "Misslyckades kopiera anteckningar frÃ¥n â€%s†till â€%sâ€" msgid "fseek failed" -msgstr "\"fseek\" misslyckades" +msgstr "â€fseek†misslyckades" #, c-format msgid "could not open '%s' for reading" -msgstr "kunde inte öppna \"%s\" för läsning" +msgstr "kunde inte öppna â€%s†för läsning" #, c-format msgid "could not open '%s' for writing" -msgstr "kunde inte öppna \"%s\" för skrivning" +msgstr "kunde inte öppna â€%s†för skrivning" #, c-format msgid "could not parse patch '%s'" -msgstr "kunde inte tolka patchen \"%s\"" +msgstr "kunde inte tolka patchen â€%sâ€" msgid "Only one StGIT patch series can be applied at once" msgstr "Endast en StGIT-patchserie kan tillämpas Ã¥t gÃ¥ngen" @@ -1968,7 +1977,7 @@ msgid "invalid timestamp" msgstr "ogiltig tidsstämpel" msgid "invalid Date line" -msgstr "ogiltig \"Date\"-rad" +msgstr "ogiltig â€Dateâ€-rad" msgid "invalid timezone offset" msgstr "ogiltig tidszons-offset" @@ -1978,29 +1987,29 @@ msgstr "Misslyckades detektera patchformat." #, c-format msgid "failed to create directory '%s'" -msgstr "misslyckades skapa katalogen \"%s\"" +msgstr "misslyckades skapa katalogen â€%sâ€" msgid "Failed to split patches." msgstr "Misslyckades dela patchar." #, c-format msgid "When you have resolved this problem, run \"%s --continue\"." -msgstr "När du har löst problemet, kör \"%s --continue\"." +msgstr "När du har löst problemet, kör â€%s --continueâ€." #, c-format msgid "If you prefer to skip this patch, run \"%s --skip\" instead." -msgstr "Om du hellre vill hoppa över patchen, kör \"%s --skip\" i stället." +msgstr "Om du hellre vill hoppa över patchen, kör â€%s --skip†i stället." #, c-format msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"." msgstr "" -"För att registrera den tomma patchen som en tom incheckning, kör \"%s --" -"allow-empty\"." +"För att registrera den tomma patchen som en tom incheckning, kör â€%s --allow-" +"emptyâ€." #, c-format msgid "To restore the original branch and stop patching, run \"%s --abort\"." msgstr "" -"För att Ã¥tergÃ¥ till ursprunglig gren och sluta patcha, kör \"%s --abort\"." +"För att Ã¥tergÃ¥ till ursprunglig gren och sluta patcha, kör â€%s --abortâ€." msgid "Patch sent with format=flowed; space at the end of lines might be lost." msgstr "" @@ -2008,7 +2017,7 @@ msgstr "" #, c-format msgid "missing author line in commit %s" -msgstr "saknad \"author\"-rad i incheckningen %s" +msgstr "saknad â€authorâ€-rad i incheckningen %s" #, c-format msgid "invalid ident line: %.*s" @@ -2095,8 +2104,7 @@ msgstr "Patch misslyckades pÃ¥ %s %.*s" msgid "Use 'git am --show-current-patch=diff' to see the failed patch" msgstr "" -"Använd \"git am --show-current-patch=diff\" för att se patchen som " -"misslyckades" +"Använd â€git am --show-current-patch=diff†för att se patchen som misslyckades" msgid "No changes - recorded it as an empty commit." msgstr "Inga ändringar - sparat som en tom incheckning." @@ -2106,7 +2114,7 @@ msgid "" "If there is nothing left to stage, chances are that something else\n" "already introduced the same changes; you might want to skip this patch." msgstr "" -"Inga ändringar - glömde du att använda \"git add\"?\n" +"Inga ändringar - glömde du att använda â€git addâ€?\n" "Om det inte är nÃ¥got kvar att köa kan det hända att nÃ¥got annat redan\n" "introducerat samma ändringar; kanske du bör hoppa över patchen." @@ -2117,16 +2125,13 @@ msgid "" "You might run `git rm` on a file to accept \"deleted by them\" for it." msgstr "" "Du har fortfarande ej sammanslagna sökvägar i indexet.\n" -"Du bör köra \"git add\" pÃ¥ filer med lösta konflikter för att ange dem som " +"Du bör köra â€git add†pÃ¥ filer med lösta konflikter för att ange dem som " "lösta.\n" -"Du kan köra \"git rm\" för att godta \"borttagen av dem\" för den." - -msgid "unable to write new index file" -msgstr "kunde inte skriva ny indexfil" +"Du kan köra â€git rm†för att godta â€borttagen av dem†för den." #, c-format msgid "Could not parse object '%s'." -msgstr "Kan inte tolka objektet \"%s\"." +msgstr "Kan inte tolka objektet â€%sâ€." msgid "failed to clean index" msgstr "misslyckades städa upp indexet" @@ -2135,16 +2140,12 @@ msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" "Not rewinding to ORIG_HEAD" msgstr "" -"Du verkar ha flyttat HEAD sedan \"am\" sist misslyckades.\n" +"Du verkar ha flyttat HEAD sedan â€am†sist misslyckades.\n" "Ã…terställer inte till ORIG_HEAD" #, c-format msgid "failed to read '%s'" -msgstr "misslyckades läsa \"%s\"" - -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "flaggorna \"%s=%s\" och \"%s=%s\" kan inte användas samtidigt" +msgstr "misslyckades läsa â€%sâ€" msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<flaggor>] [(<mbox> | <Maildir>)...]" @@ -2168,7 +2169,7 @@ msgid "be quiet" msgstr "var tyst" msgid "add a Signed-off-by trailer to the commit message" -msgstr "lägg till \"Signed-off-by\"-släprad i incheckningsmeddelandet" +msgstr "lägg till â€Signed-off-byâ€-släprad i incheckningsmeddelandet" msgid "recode into utf8 (default)" msgstr "koda om till utf8 (standard)" @@ -2265,7 +2266,7 @@ msgid "" "Use \"git am --abort\" to remove it." msgstr "" "Kvarbliven katalog %s hittades.\n" -"Använd \"git am --abort\" för att ta bort den." +"Använd â€git am --abort†för att ta bort den." msgid "Resolve operation not in progress, we are not resuming." msgstr "Lösningsoperation pÃ¥gÃ¥r inte, vi Ã¥terupptar inte." @@ -2296,10 +2297,10 @@ msgid "git archive: expected a flush" msgstr "git archive: förväntade en tömning (flush)" msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<dÃ¥lig> [<bra>...]] [--] [<sökvägar>...]" msgid "git bisect (good|bad) [<rev>...]" @@ -2314,32 +2315,32 @@ msgstr "git bisect reset [<incheckning>]" msgid "git bisect replay <logfile>" msgstr "git bisect replay <loggfil>" -msgid "git bisect run <cmd>..." -msgstr "git bisect run <kommando>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <kommando> [<argument>]..." #, c-format msgid "cannot open file '%s' in mode '%s'" -msgstr "kan inte kopiera filen \"%s\" i läget \"%s\"" +msgstr "kan inte kopiera filen â€%s†i läget â€%sâ€" #, c-format msgid "could not write to file '%s'" -msgstr "kunde inte skriva till filen \"%s\"" +msgstr "kunde inte skriva till filen â€%sâ€" #, c-format msgid "cannot open file '%s' for reading" -msgstr "kan inte öppna filen \"%s\" för läsning" +msgstr "kan inte öppna filen â€%s†för läsning" #, c-format msgid "'%s' is not a valid term" -msgstr "\"%s\" är inte en giltig term" +msgstr "â€%s†är inte en giltig term" #, c-format msgid "can't use the builtin command '%s' as a term" -msgstr "kan inte använda det inbyggda kommandot \"%s\" som term" +msgstr "kan inte använda det inbyggda kommandot â€%s†som term" #, c-format msgid "can't change the meaning of the term '%s'" -msgstr "kan inte ändra betydelsen av termen \"%s\"" +msgstr "kan inte ändra betydelsen av termen â€%sâ€" msgid "please use two different terms" msgstr "termerna mÃ¥ste vara olika" @@ -2350,14 +2351,14 @@ msgstr "Vi utför ingen bisect för tillfället.\n" #, c-format msgid "'%s' is not a valid commit" -msgstr "\"%s\" är inte en giltig incheckning" +msgstr "â€%s†är inte en giltig incheckning" #, c-format msgid "" "could not check out original HEAD '%s'. Try 'git bisect reset <commit>'." msgstr "" -"Kunde inte checka ut original-HEAD \"%s\". Försök \"git bisect reset " -"<incheckning>\"." +"Kunde inte checka ut original-HEAD â€%sâ€. Försök â€git bisect reset " +"<incheckning>â€." #, c-format msgid "Bad bisect_write argument: %s" @@ -2365,15 +2366,15 @@ msgstr "Felaktigt argument till bisect_write: %s" #, c-format msgid "couldn't get the oid of the rev '%s'" -msgstr "kan inte läsa oid för referensen \"%s\"" +msgstr "kan inte läsa oid för referensen â€%sâ€" #, c-format msgid "couldn't open the file '%s'" -msgstr "kunde inte öppna filen \"%s\"" +msgstr "kunde inte öppna filen â€%sâ€" #, c-format msgid "Invalid command: you're currently in a %s/%s bisect" -msgstr "Ogiltigt kommando: du utför just nu en \"bisect\" med %s/%s." +msgstr "Ogiltigt kommando: du utför just nu en â€bisect†med %s/%s." #, c-format msgid "" @@ -2381,7 +2382,7 @@ msgid "" "You can use \"git bisect %s\" and \"git bisect %s\" for that." msgstr "" "Du mÃ¥ste ange Ã¥tminstone en %s och en %s version.\n" -"(Du kan använda \"git bisect %s\" och \"git bisect %s\" för detta.)" +"(Du kan använda â€git bisect %s†och â€git bisect %s†för detta.)" #, c-format msgid "" @@ -2389,9 +2390,9 @@ msgid "" "You then need to give me at least one %s and %s revision.\n" "You can use \"git bisect %s\" and \"git bisect %s\" for that." msgstr "" -"Du mÃ¥ste starta med \"git bisect start\".\n" +"Du mÃ¥ste starta med â€git bisect startâ€.\n" "Du mÃ¥ste sedan ange Ã¥tminstone en %s och en %s version.\n" -"(Du kan använda \"git bisect %s\" och \"git bisect %s\" för detta.)" +"(Du kan använda â€git bisect %s†och â€git bisect %s†för detta.)" #, c-format msgid "bisecting only with a %s commit" @@ -2432,7 +2433,7 @@ msgid "" "invalid argument %s for 'git bisect terms'.\n" "Supported options are: --term-good|--term-old and --term-bad|--term-new." msgstr "" -"ogiltigt argument %s för \"git bisect terms\".\n" +"ogiltigt argument %s för â€git bisect termsâ€.\n" "Flaggor som stöds är: --term-good|--term-old och --term-bad|--term-new." msgid "revision walk setup failed\n" @@ -2440,10 +2441,10 @@ msgstr "misslyckades starta revisionstraversering\n" #, c-format msgid "could not open '%s' for appending" -msgstr "kunde inte öppna \"%s\" för tillägg" +msgstr "kunde inte öppna â€%s†för tillägg" msgid "'' is not a valid term" -msgstr "\"\" är inte en giltig term" +msgstr "â€â€ är inte en giltig term" #, c-format msgid "unrecognized option: '%s'" @@ -2451,25 +2452,24 @@ msgstr "okänd flagga: %s" #, c-format msgid "'%s' does not appear to be a valid revision" -msgstr "\"%s\" verkar inte vara en giltig revision" +msgstr "â€%s†verkar inte vara en giltig revision" msgid "bad HEAD - I need a HEAD" msgstr "felaktigt HEAD - Jag behöver ett HEAD" #, c-format msgid "checking out '%s' failed. Try 'git bisect start <valid-branch>'." -msgstr "" -"misslyckades checka ut \"%s\". Försök \"git bisect reset <giltig_gren>\"." +msgstr "misslyckades checka ut â€%sâ€. Försök â€git bisect reset <giltig_gren>â€." msgid "bad HEAD - strange symbolic ref" msgstr "felaktigt HEAD - konstig symbolisk referens" #, c-format msgid "invalid ref: '%s'" -msgstr "ogiltig referens: \"%s\"" +msgstr "ogiltig referens: â€%sâ€" msgid "You need to start by \"git bisect start\"\n" -msgstr "Du mÃ¥ste starta med \"git bisect start\"\n" +msgstr "Du mÃ¥ste starta med â€git bisect startâ€\n" #. TRANSLATORS: Make sure to include [Y] and [n] in your #. translation. The program will only accept English input @@ -2479,11 +2479,11 @@ msgid "Do you want me to do it for you [Y/n]? " msgstr "Vill du att jag ska göra det Ã¥t dig [Y=ja/N=nej]? " msgid "Please call `--bisect-state` with at least one argument" -msgstr "Anropa \"--bisect-state\" med minst ett argument." +msgstr "Anropa â€--bisect-state†med minst ett argument." #, c-format msgid "'git bisect %s' can take only one argument." -msgstr "\"git bisect %s\" kan bara ta ett argument." +msgstr "â€git bisect %s†kan bara ta ett argument." #, c-format msgid "Bad rev input: %s" @@ -2498,11 +2498,11 @@ msgstr "Vi utför ingen bisect för tillfället." #, c-format msgid "'%s'?? what are you talking about?" -msgstr "\"%s\"?? vad menar du?" +msgstr "â€%sâ€?? vad menar du?" #, c-format msgid "cannot read file '%s' for replaying" -msgstr "kan inte läsa filen \"%s\" för Ã¥teruppspelning" +msgstr "kan inte läsa filen â€%s†för Ã¥teruppspelning" #, c-format msgid "running %s\n" @@ -2521,18 +2521,17 @@ msgstr "falsk slutkod %d för bra revision" #, c-format msgid "bisect run failed: exit code %d from %s is < 0 or >= 128" -msgstr "" -"\"bisect\"-körningen misslyckades: felkod %d frÃ¥n %s är < 0 eller >= 128" +msgstr "â€bisectâ€-körningen misslyckades: felkod %d frÃ¥n %s är < 0 eller >= 128" #, c-format msgid "cannot open file '%s' for writing" -msgstr "kan inte öppna \"%s\" för skrivning" +msgstr "kan inte öppna â€%s†för skrivning" msgid "bisect run cannot continue any more" -msgstr "\"bisect\"-körningen kan inte fortsätta längre" +msgstr "â€bisectâ€-körningen kan inte fortsätta längre" msgid "bisect run success" -msgstr "\"bisect\"-körningen lyckades" +msgstr "â€bisectâ€-körningen lyckades" msgid "bisect found first bad commit" msgstr "bisect hittade första trasiga incheckning" @@ -2540,34 +2539,33 @@ msgstr "bisect hittade första trasiga incheckning" #, c-format msgid "bisect run failed: 'git bisect %s' exited with error code %d" msgstr "" -"\"bisect\"-körningen misslyckades: \"git bisect %s\" avslutades med felkoden " -"%d" +"â€bisectâ€-körningen misslyckades: â€git bisect %s†avslutades med felkoden %d" #, c-format msgid "'%s' requires either no argument or a commit" -msgstr "\"%s\" kräver antingen inget argument eller en incheckning" +msgstr "â€%s†kräver antingen inget argument eller en incheckning" #, c-format msgid "'%s' requires 0 or 1 argument" -msgstr "\"%s\" kräver noll eller ett argument" +msgstr "â€%s†kräver noll eller ett argument" #, c-format msgid "'%s' requires 0 arguments" -msgstr "\"%s\" kräver noll argument" +msgstr "â€%s†kräver noll argument" msgid "no logfile given" msgstr "ingen loggfil angiven" #, c-format msgid "'%s' failed: no command provided." -msgstr "\"%s\" misslyckades: inget kommando gavs." +msgstr "â€%s†misslyckades: inget kommando gavs." msgid "need a command" msgstr "behöver ett kommando" #, c-format msgid "unknown command: '%s'" -msgstr "okänt kommando: \"%s\"" +msgstr "okänt kommando: â€%sâ€" msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>" msgstr "git blame [<flaggor>] [<rev-flaggor>] [<rev>] [--] <fil>" @@ -2596,7 +2594,7 @@ msgid "do not show object names of boundary commits (Default: off)" msgstr "visa inte objektnamn för gränsincheckningar (Standard: av)" msgid "do not treat root commits as boundaries (Default: off)" -msgstr "vehandla inte rotincheckningar som gränser (Standard: av)" +msgstr "behandla inte rotincheckningar som gränser (Standard: av)" msgid "show work cost statistics" msgstr "visa statistik över arbetskostnad" @@ -2730,56 +2728,56 @@ msgstr "git branch [<flaggor>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" -"tar bort grenen \"%s\" som har slagits ihop med\n" -" \"%s\", men ännu inte slagits ihop med HEAD." +"tar bort grenen â€%s†som har slagits ihop med\n" +" â€%sâ€, men ännu inte slagits ihop med HEAD" #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" -"tar inte bort grenen \"%s\" som inte har slagits ihop med\n" -" \"%s\", trots att den har slagits ihop med HEAD." +"tar inte bort grenen â€%s†som inte har slagits ihop med\n" +" â€%sâ€, trots att den har slagits ihop med HEAD" #, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "Kunde inte slÃ¥ upp incheckningsobjekt för \"%s\"" +msgid "couldn't look up commit object for '%s'" +msgstr "kunde inte slÃ¥ upp incheckningsobjekt för â€%sâ€" #, 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 "" -"Grenen \"%s\" har inte slagits samman i sin helhet.\n" -"Om du är säker pÃ¥ att du vill ta bort den, kör \"git branch -D %s\"." +msgid "the branch '%s' is not fully merged" +msgstr "grenen â€%s†har inte slagits samman i sin helhet" + +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" +msgstr "Om du är säker pÃ¥ att du vill ta bort den, kör â€git branch -D %sâ€" -msgid "Update of config-file failed" -msgstr "Misslyckades uppdatera konfigurationsfil" +msgid "update of config-file failed" +msgstr "misslyckades uppdatera konfigurationsfil" msgid "cannot use -a with -d" msgstr "kan inte ange -a med -d" #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "Kan inte ta bort grenen \"%s\" som är utcheckad pÃ¥ \"%s\"" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "kan inte ta bort grenen â€%s†som används av arbetskatalogen pÃ¥ â€%sâ€" #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "fjärrspÃ¥rande grenen \"%s\" hittades inte." +msgid "remote-tracking branch '%s' not found" +msgstr "fjärrspÃ¥rande grenen â€%s†hittades inte" #, c-format msgid "" "branch '%s' not found.\n" "Did you forget --remote?" msgstr "" -"grenen \"%s\" hittades inte.\n" +"grenen â€%s†hittades inte.\n" "Glömde du --remote?" #, c-format -msgid "branch '%s' not found." -msgstr "grenen \"%s\" hittades inte." +msgid "branch '%s' not found" +msgstr "grenen â€%s†hittades inte" #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" @@ -2800,52 +2798,52 @@ msgid "HEAD (%s) points outside of refs/heads/" msgstr "HEAD (%s) pekar utenför refs/heads/" #, c-format -msgid "Branch %s is being rebased at %s" -msgstr "Grenen %s ombaseras pÃ¥ %s" +msgid "branch %s is being rebased at %s" +msgstr "grenen %s ombaseras pÃ¥ %s" #, c-format -msgid "Branch %s is being bisected at %s" -msgstr "Grenen %s är i en \"bisect\" pÃ¥ %s" +msgid "branch %s is being bisected at %s" +msgstr "grenen %s är i en â€bisect†pÃ¥ %s" #, c-format msgid "HEAD of working tree %s is not updated" msgstr "HEAD i arbetskatalogen %s har inte uppdaterats" #, c-format -msgid "Invalid branch name: '%s'" -msgstr "Felaktigt namn pÃ¥ gren: \"%s\"" +msgid "invalid branch name: '%s'" +msgstr "gelaktigt namn pÃ¥ gren: â€%sâ€" #, c-format -msgid "No commit on branch '%s' yet." -msgstr "Inga incheckningar pÃ¥ grenen \"%s\" ännu." +msgid "no commit on branch '%s' yet" +msgstr "inga incheckningar pÃ¥ grenen â€%s†ännu" #, c-format -msgid "No branch named '%s'." -msgstr "Ingen gren vid namnet \"%s\"." +msgid "no branch named '%s'" +msgstr "ingen gren vid namnet â€%sâ€" -msgid "Branch rename failed" -msgstr "Misslyckades byta namn pÃ¥ gren" +msgid "branch rename failed" +msgstr "misslyckades byta namn pÃ¥ gren" -msgid "Branch copy failed" -msgstr "Misslyckades kopiera gren" +msgid "branch copy failed" +msgstr "misslyckades kopiera gren" #, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "Skapade kopia av felaktigt namngiven gren \"%s\"" +msgid "created a copy of a misnamed branch '%s'" +msgstr "skapade kopia av felaktigt namngiven gren â€%sâ€" #, c-format -msgid "Renamed a misnamed branch '%s' away" -msgstr "Bytte bort namn pÃ¥ en felaktigt namngiven gren \"%s\"" +msgid "renamed a misnamed branch '%s' away" +msgstr "bytte bort namn pÃ¥ en felaktigt namngiven gren â€%sâ€" #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "Grenen namnbytt till %s, men HEAD har inte uppdaterats!" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "grenen namnbytt till %s, men HEAD har inte uppdaterats" -msgid "Branch is renamed, but update of config-file failed" -msgstr "Grenen namnbytt, men misslyckades uppdatera konfigurationsfilen" +msgid "branch is renamed, but update of config-file failed" +msgstr "grenen namnbytt, men misslyckades uppdatera konfigurationsfilen" -msgid "Branch is copied, but update of config-file failed" -msgstr "Grenen kopierades, men misslyckades uppdatera konfigurationsfilen" +msgid "branch is copied, but update of config-file failed" +msgstr "grenen kopierades, men misslyckades uppdatera konfigurationsfilen" #, c-format msgid "" @@ -2855,7 +2853,7 @@ msgid "" msgstr "" "Redigera beskrivningen för grenen\n" " %s\n" -"Rader som inleds med \"%c\" ignoreras.\n" +"Rader som inleds med â€%c†ignoreras.\n" msgid "Generic options" msgstr "Allmänna flaggor" @@ -2959,8 +2957,8 @@ msgstr "rekursera ner i undermoduler" msgid "format to use for the output" msgstr "format att använda för utdata" -msgid "Failed to resolve HEAD as a valid ref." -msgstr "Misslyckades slÃ¥ upp HEAD som giltig referens." +msgid "failed to resolve HEAD as a valid ref" +msgstr "misslyckades slÃ¥ upp HEAD som giltig referens" msgid "HEAD not found below refs/heads!" msgstr "HEAD hittades inte under refs/heads!" @@ -2978,18 +2976,17 @@ msgstr "--recurse-submodules kan endast användas för att skapa grenar" msgid "branch name required" msgstr "grennamn krävs" -msgid "Cannot give description to detached HEAD" -msgstr "Kan inte beskriva frÃ¥nkopplad HEAD" +msgid "cannot give description to detached HEAD" +msgstr "kan inte beskriva frÃ¥nkopplad HEAD" msgid "cannot edit description of more than one branch" msgstr "kan inte redigera beskrivning för mer än en gren" -msgid "cannot copy the current branch while not on any." -msgstr "kunde inte kopiera aktuell gren när du inte befinner dig pÃ¥ nÃ¥gon." +msgid "cannot copy the current branch while not on any" +msgstr "kunde inte kopiera aktuell gren när du inte befinner dig pÃ¥ nÃ¥gon" -msgid "cannot rename the current branch while not on any." -msgstr "" -"kunde inte byta namn pÃ¥ aktuell gren när du inte befinner dig pÃ¥ nÃ¥gon." +msgid "cannot rename the current branch while not on any" +msgstr "kunde inte byta namn pÃ¥ aktuell gren när du inte befinner dig pÃ¥ nÃ¥gon" msgid "too many branches for a copy operation" msgstr "för mÃ¥nga grenar för kopiering" @@ -3002,49 +2999,48 @@ msgstr "för mÃ¥nga flaggor för att byta uppström" #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." +"could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" -"kunde inte sätta uppström för HEAD till %s när det inte pekar mot nÃ¥gon gren." +"kunde inte sätta uppström för HEAD till %s när det inte pekar mot nÃ¥gon gren" #, c-format msgid "no such branch '%s'" -msgstr "okänd gren \"%s\"" +msgstr "okänd gren â€%sâ€" #, c-format msgid "branch '%s' does not exist" -msgstr "grenen \"%s\" finns inte" +msgstr "grenen â€%s†finns inte" msgid "too many arguments to unset upstream" msgstr "för mÃ¥nga flaggor för att ta bort uppström" -msgid "could not unset upstream of HEAD when it does not point to any branch." -msgstr "" -"kunde inte ta bort uppström för HEAD när det inte pekar mot nÃ¥gon gren." +msgid "could not unset upstream of HEAD when it does not point to any branch" +msgstr "kunde inte ta bort uppström för HEAD när det inte pekar mot nÃ¥gon gren" #, c-format -msgid "Branch '%s' has no upstream information" -msgstr "Grenen \"%s\" har ingen uppströmsinformation" +msgid "branch '%s' has no upstream information" +msgstr "grenen â€%s†har ingen uppströmsinformation" msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"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 "" -"Flaggorna -a och -r pÃ¥ \"git branch\" tar inte ett namn pÃ¥ gren.\n" +"flaggorna -a och -r pÃ¥ â€git branch†tar inte ett namn pÃ¥ gren.\n" "Menade du att använda: -a|-r --list <mönster>?" msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." +"'--set-upstream-to' instead" msgstr "" -"Flaggan --set-upstream rekommenderas ej och kommer tas bort. Använd --track " -"eller --set-upstream-to istället." +"flaggan â€--set-upstream†rekommenderas ej och kommer tas bort. Använd â€--" +"track†eller â€--set-upstream-to†istället" msgid "git version:\n" msgstr "git version:\n" #, c-format msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() misslyckades med felet \"%s\" (%d)\n" +msgstr "uname() misslyckades med felet â€%s†(%d)\n" msgid "compiler info: " msgstr "kompilatorinfo:" @@ -3103,8 +3099,7 @@ msgstr "läge" msgid "" "create an additional zip archive of detailed diagnostics (default 'stats')" msgstr "" -"skapa ett ytterligare zip-arkiv med detaljerad diagnostik (förval är \"stats" -"\")" +"skapa ett ytterligare zip-arkiv med detaljerad diagnostik (förval är â€statsâ€)" msgid "specify a destination for the bugreport file(s)" msgstr "ange mÃ¥l för buggrapporteringsfilen/-rna" @@ -3113,8 +3108,12 @@ msgid "specify a strftime format suffix for the filename(s)" msgstr "ange filändelse i strftime-format" #, c-format +msgid "unknown argument `%s'" +msgstr "okänt argument â€%sâ€" + +#, c-format msgid "could not create leading directories for '%s'" -msgstr "kunde inte skapa inledande kataloger för \"%s\"" +msgstr "kunde inte skapa inledande kataloger för â€%sâ€" #, c-format msgid "unable to create diagnostics archive %s" @@ -3132,7 +3131,7 @@ msgstr "kunde inte skriva till %s" #, c-format msgid "Created new report at '%s'.\n" -msgstr "Skapade ny rapport pÃ¥ \"%s\"\n" +msgstr "Skapade ny rapport pÃ¥ â€%sâ€\n" msgid "" "git bundle create [-q | --quiet | --progress]\n" @@ -3186,17 +3185,17 @@ msgstr "Packar upp objektbunt" #, c-format msgid "cannot read object %s '%s'" -msgstr "kan inte läsa objektet %s: \"%s\"" +msgstr "kan inte läsa objektet %s: â€%sâ€" msgid "flush is only for --buffer mode" -msgstr "flush är endast till för \"--buffer\"-läge" +msgstr "flush är endast till för â€--bufferâ€-läge" msgid "empty command in input" msgstr "tomt kommando i indata" #, c-format msgid "whitespace before command: '%s'" -msgstr "blanksteg före kommando: \"%s\"" +msgstr "blanksteg före kommando: â€%sâ€" #, c-format msgid "%s requires arguments" @@ -3219,6 +3218,14 @@ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objekt>" msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<revision>:<sökväg|träd-igt> | --path=<sökväg|träd-igt> " +"<revision>]" + +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -3229,14 +3236,6 @@ msgstr "" " [--buffer] [--follow-symlinks] [--unordered]\n" " [--textconv | --filters] [-Z]" -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<revision>:<sökväg|träd-igt> | --path=<sökväg|träd-igt> " -"<revision>]" - msgid "Check object existence or emit object contents" msgstr "Kontrollera om objektet finns eller mata ut objektets innehÃ¥ll" @@ -3250,7 +3249,7 @@ msgid "Emit [broken] object attributes" msgstr "Skriv ut [trasiga] objektattribut" msgid "show object type (one of 'blob', 'tree', 'commit', 'tag', ...)" -msgstr "visa objekttyp (en av: \"blob\", \"tree\", \"commit\", \"tag\", ...)" +msgstr "visa objekttyp (en av: â€blobâ€, â€treeâ€, â€commitâ€, â€tagâ€, ...)" msgid "show object size" msgstr "visa objektstorlek" @@ -3322,22 +3321,22 @@ msgstr "sökväg|träd-igt" #, c-format msgid "'%s' requires a batch mode" -msgstr "\"%s\" behöver ett buntläge" +msgstr "â€%s†behöver ett buntläge" #, c-format msgid "'-%c' is incompatible with batch mode" -msgstr "\"-%c\" är inkompatibel med buntläge" +msgstr "â€-%c†är inkompatibel med buntläge" msgid "batch modes take no arguments" msgstr "buntlägen inte nÃ¥gra argument" #, c-format msgid "<rev> required with '%s'" -msgstr "<rev> krävs med \"%s\"" +msgstr "<rev> krävs med â€%sâ€" #, c-format msgid "<object> required with '-%c'" -msgstr "<objekt> krävs med \"-%c\"" +msgstr "<objekt> krävs med â€-%câ€" #, c-format msgid "only two arguments allowed in <type> <object> mode, not %d" @@ -3426,7 +3425,7 @@ msgid "git checkout-index [<options>] [--] [<file>...]" msgstr "git checkout-index [<flaggor>] [--] [<fil>...]" msgid "stage should be between 1 and 3 or all" -msgstr "etapp mÃ¥ste vara mellan 1 och 3 eller \"all\"" +msgstr "etapp mÃ¥ste vara mellan 1 och 3 eller â€allâ€" msgid "check out all files in the index" msgstr "checka ut alla filer i indexet" @@ -3469,27 +3468,27 @@ msgstr "git restore [<flaggor>] [--source=<gren>] <fil>..." #, c-format msgid "path '%s' does not have our version" -msgstr "sökvägen \"%s\" har inte vÃ¥r version" +msgstr "sökvägen â€%s†har inte vÃ¥r version" #, c-format msgid "path '%s' does not have their version" -msgstr "sökvägen \"%s\" har inte deras version" +msgstr "sökvägen â€%s†har inte deras version" #, c-format msgid "path '%s' does not have all necessary versions" -msgstr "sökvägen \"%s\" innehÃ¥ller inte alla nödvändiga versioner" +msgstr "sökvägen â€%s†innehÃ¥ller inte alla nödvändiga versioner" #, c-format msgid "path '%s' does not have necessary versions" -msgstr "sökvägen \"%s\" innehÃ¥ller inte nödvändiga versioner" +msgstr "sökvägen â€%s†innehÃ¥ller inte nödvändiga versioner" #, c-format msgid "path '%s': cannot merge" -msgstr "sökväg \"%s\": kan inte slÃ¥ ihop" +msgstr "sökväg â€%sâ€: kan inte slÃ¥ ihop" #, c-format msgid "Unable to add merge result for '%s'" -msgstr "Kunde inte lägga till sammanslagningsresultat för \"%s\"" +msgstr "Kunde inte lägga till sammanslagningsresultat för â€%sâ€" #, c-format msgid "Recreated %d merge conflict" @@ -3511,27 +3510,31 @@ msgstr[1] "Uppdaterade %d sökvägar frÃ¥n indexet" #, c-format msgid "'%s' cannot be used with updating paths" -msgstr "\"%s\" kan inte användas vid uppdatering av sökvägar" +msgstr "â€%s†kan inte användas vid uppdatering av sökvägar" #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." -msgstr "Kan inte uppdatera sökvägar och växla till grenen \"%s\" samtidigt." +msgstr "Kan inte uppdatera sökvägar och växla till grenen â€%s†samtidigt." #, c-format msgid "neither '%s' or '%s' is specified" -msgstr "varken \"%s\" eller \"%s\" har angivits" +msgstr "varken â€%s†eller â€%s†har angivits" #, c-format msgid "'%s' must be used when '%s' is not specified" -msgstr "\"%s\" mÃ¥ste användas när \"%s\" inte anges" +msgstr "â€%s†mÃ¥ste användas när â€%s†inte anges" #, c-format msgid "'%s' or '%s' cannot be used with %s" -msgstr "\"%s\" eller \"%s\" kan inte användas med %s" +msgstr "â€%s†eller â€%s†kan inte användas med %s" + +#, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "â€%sâ€, â€%s†eller â€%s†kan inte användas när en katalog checkas ut" #, c-format msgid "path '%s' is unmerged" -msgstr "sökvägen \"%s\" har inte slagits ihop" +msgstr "sökvägen â€%s†har inte slagits ihop" msgid "you need to resolve your current index first" msgstr "du mÃ¥ste lösa ditt befintliga index först" @@ -3546,7 +3549,7 @@ msgstr "" #, c-format msgid "Can not do reflog for '%s': %s\n" -msgstr "Kan inte skapa referenslogg för \"%s\": %s\n" +msgstr "Kan inte skapa referenslogg för â€%sâ€: %s\n" msgid "HEAD is now at" msgstr "HEAD är nu pÃ¥" @@ -3556,23 +3559,23 @@ msgstr "kan inte uppdatera HEAD" #, c-format msgid "Reset branch '%s'\n" -msgstr "Ã…terställ gren \"%s\"\n" +msgstr "Ã…terställ gren â€%sâ€\n" #, c-format msgid "Already on '%s'\n" -msgstr "Redan pÃ¥ \"%s\"\n" +msgstr "Redan pÃ¥ â€%sâ€\n" #, c-format msgid "Switched to and reset branch '%s'\n" -msgstr "Växlade till och nollställde grenen \"%s\"\n" +msgstr "Växlade till och nollställde grenen â€%sâ€\n" #, c-format msgid "Switched to a new branch '%s'\n" -msgstr "Växlade till en ny gren \"%s\"\n" +msgstr "Växlade till en ny gren â€%sâ€\n" #, c-format msgid "Switched to branch '%s'\n" -msgstr "Växlade till grenen \"%s\"\n" +msgstr "Växlade till grenen â€%sâ€\n" #, c-format msgid " ... and %d more.\n" @@ -3640,7 +3643,7 @@ msgid "" "'%s' could be both a local file and a tracking branch.\n" "Please use -- (and optionally --no-guess) to disambiguate" msgstr "" -"\"%s\" kan vara bÃ¥de en lokal fil och en spÃ¥rande gren.\n" +"â€%s†kan vara bÃ¥de en lokal fil och en spÃ¥rande gren.\n" "Använd -- (och möjligen --no-guess) för att göra otvetydig" msgid "" @@ -3653,18 +3656,18 @@ msgid "" "one remote, e.g. the 'origin' remote, consider setting\n" "checkout.defaultRemote=origin in your config." msgstr "" -"Om du menade checka ut en spÃ¥rad fjärrgren pÃ¥ t.ex \"origin\", kan du\n" +"Om du menade checka ut en spÃ¥rad fjärrgren pÃ¥ t.ex â€originâ€, kan du\n" "göra det genom att ange hela namnet med flaggan --track:\n" "\n" " git checkout --track origin/<namn>\n" "\n" "Om du alltid vill att utcheckningar med tvetydiga <namn> ska\n" -"föredra en fjärr, t.ex fjärren \"origin\" kan du ställa in\n" +"föredra en fjärr, t.ex fjärren â€origin†kan du ställa in\n" "checkout.defaultRemote=origin i din konfiguration." #, c-format msgid "'%s' matched multiple (%d) remote tracking branches" -msgstr "\"%s\" motsvarar flera (%d) spÃ¥rade fjärrgrenar" +msgstr "â€%s†motsvarar flera (%d) spÃ¥rade fjärrgrenar" msgid "only one reference expected" msgstr "endast en referens förväntades" @@ -3683,19 +3686,19 @@ msgstr "referensen är inte ett träd: %s" #, c-format msgid "a branch is expected, got tag '%s'" -msgstr "förväntade gren, fick taggen \"%s\"" +msgstr "förväntade gren, fick taggen â€%sâ€" #, c-format msgid "a branch is expected, got remote branch '%s'" -msgstr "förväntade gren, fick fjärrgrenen \"%s\"" +msgstr "förväntade gren, fick fjärrgrenen â€%sâ€" #, c-format msgid "a branch is expected, got '%s'" -msgstr "förväntade gren, fick \"%s\"" +msgstr "förväntade gren, fick â€%sâ€" #, c-format msgid "a branch is expected, got commit '%s'" -msgstr "förväntade gren, fick incheckningen \"%s\"" +msgstr "förväntade gren, fick incheckningen â€%sâ€" msgid "" "If you want to detach HEAD at the commit, try again with the --detach option." @@ -3708,57 +3711,57 @@ msgid "" "Consider \"git merge --quit\" or \"git worktree add\"." msgstr "" "kan inte växla gren vid sammanslagning\n" -"Överväg \"git merge --quit\" eller \"git worktree add\"." +"Överväg â€git merge --quit†eller â€git worktree addâ€." msgid "" "cannot switch branch in the middle of an am session\n" "Consider \"git am --quit\" or \"git worktree add\"." msgstr "" -"kan inte växla gren mitt i en \"am\"-körning\n" -"Överväg \"git am --quit\" eller \"git worktree add\"." +"kan inte växla gren mitt i en â€amâ€-körning\n" +"Överväg â€git am --quit†eller â€git worktree addâ€." msgid "" "cannot switch branch while rebasing\n" "Consider \"git rebase --quit\" or \"git worktree add\"." msgstr "" "kan inte växla gren vid ombasering\n" -"Överväg \"git rebase --quit\" eller \"git worktree add\"." +"Överväg â€git rebase --quit†eller â€git worktree addâ€." msgid "" "cannot switch branch while cherry-picking\n" "Consider \"git cherry-pick --quit\" or \"git worktree add\"." msgstr "" -"kan inte växla gren i en \"cherry-pick\"\n" -"Överväg \"git cherry-pick --quit\" eller \"git worktree add\"." +"kan inte växla gren i en â€cherry-pickâ€\n" +"Överväg â€git cherry-pick --quit†eller â€git worktree addâ€." msgid "" "cannot switch branch while reverting\n" "Consider \"git revert --quit\" or \"git worktree add\"." msgstr "" -"kan inte växla gren i en \"revert\"\n" -"Överväg \"git revert --quit\" eller \"git worktree add\"." +"kan inte växla gren i en â€revertâ€\n" +"Överväg â€git revert --quit†eller â€git worktree addâ€." msgid "you are switching branch while bisecting" -msgstr "dÃ¥ växlar grenar medan du gör en \"bisect\"" +msgstr "dÃ¥ växlar grenar medan du gör en â€bisectâ€" msgid "paths cannot be used with switching branches" msgstr "sökvägar kan inte användas vid byte av gren" #, c-format msgid "'%s' cannot be used with switching branches" -msgstr "\"%s\" kan inte användas vid byte av gren" +msgstr "â€%s†kan inte användas vid byte av gren" #, c-format msgid "'%s' cannot be used with '%s'" -msgstr "\"%s\" kan inte användas med \"%s\"" +msgstr "â€%s†kan inte användas med â€%sâ€" #, c-format msgid "'%s' cannot take <start-point>" -msgstr "\"%s\" kan inte ta <startpunkt>" +msgstr "â€%s†kan inte ta <startpunkt>" #, c-format msgid "Cannot switch branch to a non-commit '%s'" -msgstr "Kan inte växla gren till icke-incheckningen \"%s\"" +msgstr "Kan inte växla gren till icke-incheckningen â€%sâ€" msgid "missing branch or commit argument" msgstr "saknar gren- eller incheckingsargument" @@ -3781,8 +3784,8 @@ msgstr "tvinga utcheckning (kasta bort lokala ändringar)" msgid "new-branch" msgstr "ny-gren" -msgid "new unparented branch" -msgstr "ny gren utan förälder" +msgid "new unborn branch" +msgstr "ny ofödd gren" msgid "update ignored files (default)" msgstr "uppdatera ignorerade filer (standard)" @@ -3802,7 +3805,7 @@ msgstr "begränsa inte sökvägar till endast glesa poster" #, c-format msgid "options '-%c', '-%c', and '%s' cannot be used together" -msgstr "flaggorna \"%-c\", \"-%c\" och \"%s\" kan inte användas samtidigt" +msgstr "flaggorna â€%-câ€, â€-%c†och â€%s†kan inte användas samtidigt" msgid "--track needs a branch name" msgstr "--track behöver ett namn pÃ¥ en gren" @@ -3820,12 +3823,11 @@ msgstr "felaktig sökvägsangivelse" #, c-format msgid "'%s' is not a commit and a branch '%s' cannot be created from it" -msgstr "" -"\"%s\" är inte en incheckning och grenen \"%s\" kan inte skapas frÃ¥n den" +msgstr "â€%s†är inte en incheckning och grenen â€%s†kan inte skapas frÃ¥n den" #, c-format msgid "git checkout: --detach does not take a path argument '%s'" -msgstr "git checkout: --detach tar inte en sökväg som argument \"%s\"" +msgstr "git checkout: --detach tar inte en sökväg som argument â€%sâ€" msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" @@ -3850,7 +3852,7 @@ msgid "create reflog for new branch" msgstr "skapa reflogg för ny gren" msgid "second guess 'git checkout <no-such-branch>' (default)" -msgstr "förutspÃ¥ \"git checkout <gren-saknas>\" (förval)" +msgstr "förutspÃ¥ â€git checkout <gren-saknas>†(förval)" msgid "use overlay mode (default)" msgstr "använd överläggsläge (standard)" @@ -3862,7 +3864,7 @@ msgid "create/reset and switch to a branch" msgstr "skapa/nollställ och växla till en gren" msgid "second guess 'git switch <no-such-branch>'" -msgstr "förutspÃ¥ \"git checkout <gren-saknas>\"" +msgstr "förutspÃ¥ â€git checkout <gren-saknas>â€" msgid "throw away local modifications" msgstr "kasta bort lokala ändringar" @@ -3910,7 +3912,7 @@ msgstr "misslyckades ta bort %s" #, c-format msgid "could not lstat %s\n" -msgstr "kunde inte ta status (\"lstat\") pÃ¥ %s\n" +msgstr "kunde inte ta status (â€lstatâ€) pÃ¥ %s\n" msgid "Refusing to remove current working directory\n" msgstr "Vägrar ta bort aktuell arbetskatalog\n" @@ -3982,7 +3984,7 @@ msgstr "" "clean - börja städa\n" "filter by pattern - uteslut poster frÃ¥n borttagning\n" "select by numbers - markera poster som ska tas bort med siffror\n" -"ask each - bekräfta varje borttagning (som \"rm -i\")\n" +"ask each - bekräfta varje borttagning (som â€rm -iâ€)\n" "quit - sluta städa\n" "help - denna skärm\n" "? - hjälp för kommandoval" @@ -4033,9 +4035,6 @@ msgstr "" "clean.requireForce har standardvärdet true och varken -i, -n eller -f " "angavs; vägrar städa" -msgid "-x and -X cannot be used together" -msgstr "-x och -X kan inte användas samtidigt" - msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<flaggor>] [--] <arkiv> [<kat>]" @@ -4046,10 +4045,10 @@ msgid "don't create a checkout" msgstr "skapa inte nÃ¥gon utcheckning" msgid "create a bare repository" -msgstr "skapa ett naket (\"bare\") arkiv" +msgstr "skapa ett naket (â€bareâ€) arkiv" msgid "create a mirror repository (implies bare)" -msgstr "skapa ett spegelarkiv (implicerar \"bare\")" +msgstr "skapa ett spegelarkiv (implicerar â€bareâ€)" msgid "to clone from a local repository" msgstr "för att klona frÃ¥n ett lokalt arkiv" @@ -4085,7 +4084,7 @@ msgid "name" msgstr "namn" msgid "use <name> instead of 'origin' to track upstream" -msgstr "använd <namn> istället för \"origin\" för att spÃ¥ra uppströms" +msgstr "använd <namn> istället för â€origin†för att spÃ¥ra uppströms" msgid "checkout <branch> instead of the remote's HEAD" msgstr "checka ut <gren> istället för fjärrens HEAD" @@ -4123,6 +4122,9 @@ msgstr "gitkat" msgid "separate git dir from working tree" msgstr "separera gitkatalogen frÃ¥n arbetskatalogen" +msgid "specify the reference format to use" +msgstr "använd referensformatet som ska användas" + msgid "key=value" msgstr "nyckel=värde" @@ -4152,11 +4154,11 @@ msgstr "en URI för att hämta buntar innan de hämtas frÃ¥n ursprungsfjärr" #, c-format msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info: Kan inte skapa suppleant för \"%s\": %s\n" +msgstr "info: Kan inte skapa suppleant för â€%sâ€: %s\n" #, c-format msgid "failed to stat '%s'" -msgstr "misslyckades ta status pÃ¥ \"%s\"" +msgstr "misslyckades ta status pÃ¥ â€%sâ€" #, c-format msgid "%s exists and is not a directory" @@ -4164,31 +4166,31 @@ msgstr "%s finns och är ingen katalog" #, c-format msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "\"%s\" är en symbolisk länk, vägrar klona med --local" +msgstr "â€%s†är en symbolisk länk, vägrar klona med --local" #, c-format msgid "failed to start iterator over '%s'" -msgstr "misslyckades starta iterator över \"%s\"" +msgstr "misslyckades starta iterator över â€%sâ€" #, c-format msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "symbolisk länk \"%s\" finns redan, vägrar klona med --local" +msgstr "symbolisk länk â€%s†finns redan, vägrar klona med --local" #, c-format msgid "failed to unlink '%s'" -msgstr "misslyckades ta bort länken \"%s\"" +msgstr "misslyckades ta bort länken â€%sâ€" #, c-format msgid "failed to create link '%s'" -msgstr "misslyckades skapa länken \"%s\"" +msgstr "misslyckades skapa länken â€%sâ€" #, c-format msgid "failed to copy file to '%s'" -msgstr "misslyckades kopiera filen till \"%s\"" +msgstr "misslyckades kopiera filen till â€%sâ€" #, c-format msgid "failed to iterate over '%s'" -msgstr "misslyckades iterera över \"%s\"" +msgstr "misslyckades iterera över â€%sâ€" #, c-format msgid "done.\n" @@ -4200,8 +4202,8 @@ msgid "" "and retry with 'git restore --source=HEAD :/'\n" msgstr "" "Klonen lyckades, men utcheckningen misslyckades.\n" -"Du kan inspektera det som checkades ut med \"git status\"\n" -"och försöka med \"git restore --source=HEAD :/\"\n" +"Du kan inspektera det som checkades ut med â€git statusâ€\n" +"och försöka med â€git restore --source=HEAD :/â€\n" #, c-format msgid "Could not find remote branch %s to clone." @@ -4230,7 +4232,7 @@ msgid "cannot repack to clean up" msgstr "kan inte packa om för att städa upp" msgid "cannot unlink temporary alternates file" -msgstr "kunde inte ta bort temporär \"alternates\"-fil" +msgstr "kunde inte ta bort temporär â€alternatesâ€-fil" msgid "Too many arguments." msgstr "För mÃ¥nga argument." @@ -4238,16 +4240,13 @@ msgstr "För mÃ¥nga argument." msgid "You must specify a repository to clone." msgstr "Du mÃ¥ste ange ett arkiv att klona." -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "" -"--bundle-uri är inkompatibelt med --depth, --shallow-since och --shallow-" -"exclude" +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "okänt format för lagring av referenser â€%sâ€" #, c-format msgid "repository '%s' does not exist" -msgstr "arkivet \"%s\" finns inte" +msgstr "arkivet â€%s†finns inte" #, c-format msgid "depth %s is not a positive number" @@ -4255,31 +4254,31 @@ msgstr "djupet %s är inte ett positivt tal" #, c-format msgid "destination path '%s' already exists and is not an empty directory." -msgstr "destinationssökvägen \"%s\" finns redan och är inte en tom katalog." +msgstr "destinationssökvägen â€%s†finns redan och är inte en tom katalog." #, c-format msgid "repository path '%s' already exists and is not an empty directory." -msgstr "arkivsökvägen \"%s\" finns redan och är inte en tom katalog." +msgstr "arkivsökvägen â€%s†finns redan och är inte en tom katalog." #, c-format msgid "working tree '%s' already exists." -msgstr "arbetsträdet \"%s\" finns redan." +msgstr "arbetsträdet â€%s†finns redan." #, c-format msgid "could not create leading directories of '%s'" -msgstr "kunde inte skapa inledande kataloger för \"%s\"" +msgstr "kunde inte skapa inledande kataloger för â€%sâ€" #, c-format msgid "could not create work tree dir '%s'" -msgstr "kunde inte skapa arbetskatalogen \"%s\"" +msgstr "kunde inte skapa arbetskatalogen â€%sâ€" #, c-format msgid "Cloning into bare repository '%s'...\n" -msgstr "Klonar till ett naket arkiv \"%s\"...\n" +msgstr "Klonar till ett naket arkiv â€%sâ€...\n" #, c-format msgid "Cloning into '%s'...\n" -msgstr "Klonar till \"%s\"...\n" +msgstr "Klonar till â€%sâ€...\n" msgid "" "clone --recursive is not compatible with both --reference and --reference-if-" @@ -4289,7 +4288,7 @@ msgstr "" #, c-format msgid "'%s' is not a valid remote name" -msgstr "\"%s\" är inte ett giltigt namn pÃ¥ fjärrarkiv" +msgstr "â€%s†är inte ett giltigt namn pÃ¥ fjärrarkiv" msgid "--depth is ignored in local clones; use file:// instead." msgstr "--depth ignoreras i lokala kloningar; använd file:// istället." @@ -4321,7 +4320,7 @@ msgstr "misslyckades initiera arkivet, hoppar över bunt-URI" #, c-format msgid "failed to fetch objects from bundle URI '%s'" -msgstr "misslyckades hämta objekt frÃ¥n bunt-URI \"%s\"" +msgstr "misslyckades hämta objekt frÃ¥n bunt-URI â€%sâ€" msgid "failed to fetch advertised bundles" msgstr "misslyckades hämta annonserade buntar" @@ -4371,7 +4370,7 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <kat>] [--append]\n" " [--split[=<strategi>]] [--reachable | --stdin-packs | " @@ -4391,7 +4390,11 @@ msgstr "om inchecknignsgrafen är delad, kontrollera bara spetsfilen" #, c-format msgid "Could not open commit-graph '%s'" -msgstr "Kunde inte öppna incheckningsgrafen \"%s\"" +msgstr "Kunde inte öppna incheckningsgrafen â€%sâ€" + +#, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "kunde inte öppna incheckningsgrafen â€%sâ€" #, c-format msgid "unrecognized --split argument, %s" @@ -4407,7 +4410,7 @@ msgstr "ogiltigt objekt: %s" #, c-format msgid "option `%s' expects a numerical value" -msgstr "flaggan \"%s\" antar ett numeriskt värde" +msgstr "flaggan â€%s†antar ett numeriskt värde" msgid "start walk at all refs" msgstr "starta traversering vid alla referenser" @@ -4467,11 +4470,11 @@ msgstr "objektnamnet är inte giltigt: %s" #, c-format msgid "git commit-tree: failed to read '%s'" -msgstr "git commit-tree: misslyckades läsa \"%s\"" +msgstr "git commit-tree: misslyckades läsa â€%sâ€" #, c-format msgid "git commit-tree: failed to close '%s'" -msgstr "git commit-tree: misslyckades stänga \"%s\"" +msgstr "git commit-tree: misslyckades stänga â€%sâ€" msgid "parent" msgstr "förälder" @@ -4529,7 +4532,7 @@ msgid "" msgstr "" "Du bad om att utöka den senaste incheckningen, men om du gör det\n" "blir den tom. Du kan köra kommandot pÃ¥ nytt med --allow-empty, eller\n" -"sÃ¥ kan du ta bort incheckningen helt med \"git reset HEAD^\".\n" +"sÃ¥ kan du ta bort incheckningen helt med â€git reset HEAD^â€.\n" msgid "" "The previous cherry-pick is now empty, possibly due to conflict resolution.\n" @@ -4538,17 +4541,17 @@ msgid "" " git commit --allow-empty\n" "\n" msgstr "" -"Den tidigare \"cherry-pick\":en är nu tom, kanske pÃ¥ grund av en löst\n" +"Den tidigare â€cherry-pickâ€:en är nu tom, kanske pÃ¥ grund av en löst\n" "konflikt. Om du vill checka in den ändÃ¥ använder du:\n" "\n" " git commit --allow-empty\n" "\n" msgid "Otherwise, please use 'git rebase --skip'\n" -msgstr "Använd annars \"git rebase --skip\"\n" +msgstr "Använd annars â€git rebase --skipâ€\n" msgid "Otherwise, please use 'git cherry-pick --skip'\n" -msgstr "Använd annars \"git cherry-pick --skip\"\n" +msgstr "Använd annars â€git cherry-pick --skipâ€\n" msgid "" "and then use:\n" @@ -4565,7 +4568,7 @@ msgstr "" "\n" " git cherry-pick --continue\n" "\n" -"för att fortsätta \"cherry-pick\" med resterande incheckningar.\n" +"för att fortsätta â€cherry-pick†med resterande incheckningar.\n" "Om du vill hoppa över den här incheckningen, använd:\n" "\n" " git cherry-pick --skip\n" @@ -4592,9 +4595,6 @@ msgstr "kan inte uppdatera temporärt index" msgid "Failed to update main cache tree" msgstr "Misslyckades uppdatera huvud-cacheträdet" -msgid "unable to write new_index file" -msgstr "kunde inte skriva filen new_index" - msgid "cannot do a partial commit during a merge." msgstr "kan inte utföra en delvis incheckning under en sammanslagning." @@ -4612,14 +4612,14 @@ msgstr "kunde inte skriva temporär indexfil" #, c-format msgid "commit '%s' lacks author header" -msgstr "incheckningen \"%s\" saknar författarhuvud" +msgstr "incheckningen â€%s†saknar författarhuvud" #, c-format msgid "commit '%s' has malformed author line" -msgstr "incheckningen \"%s\" har felformaterat författarhuvud" +msgstr "incheckningen â€%s†har felformaterat författarhuvud" msgid "malformed --author parameter" -msgstr "felformad \"--author\"-flagga" +msgstr "felformad â€--authorâ€-flagga" #, c-format msgid "invalid date format: %s" @@ -4634,7 +4634,7 @@ msgstr "" #, c-format msgid "could not lookup commit '%s'" -msgstr "kunde inte slÃ¥ upp incheckningen \"%s\"" +msgstr "kunde inte slÃ¥ upp incheckningen â€%sâ€" #, c-format msgid "(reading log message from standard input)\n" @@ -4645,11 +4645,11 @@ msgstr "kunde inte läsa logg frÃ¥n standard in" #, c-format msgid "could not read log file '%s'" -msgstr "kunde inte läsa loggfilen \"%s\"" +msgstr "kunde inte läsa loggfilen â€%sâ€" #, c-format msgid "options '%s' and '%s:%s' cannot be used together" -msgstr "flaggorna \"%s\" och \"%s:%s\" kan inte användas samtidigt" +msgstr "flaggorna â€%s†och â€%s:%s†kan inte användas samtidigt" msgid "could not read SQUASH_MSG" msgstr "kunde inte läsa SQUASH_MSG" @@ -4659,7 +4659,7 @@ msgstr "kunde inte läsa MERGE_MSG" #, c-format msgid "could not open '%s'" -msgstr "kunde inte öppna \"%s\"" +msgstr "kunde inte öppna â€%sâ€" msgid "could not write commit template" msgstr "kunde inte skriva incheckningsmall" @@ -4670,7 +4670,7 @@ msgid "" "with '%c' will be ignored.\n" msgstr "" "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n" -"med \"%c\" kommer ignoreras.\n" +"med â€%c†kommer ignoreras.\n" #, c-format msgid "" @@ -4678,8 +4678,7 @@ msgid "" "with '%c' will be ignored, and an empty message aborts the commit.\n" msgstr "" "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n" -"med \"%c\" kommer ignoreras, och ett tomt meddelande avbryter " -"incheckningen.\n" +"med â€%c†kommer ignoreras, och ett tomt meddelande avbryter incheckningen.\n" #, c-format msgid "" @@ -4687,7 +4686,7 @@ msgid "" "with '%c' will be kept; you may remove them yourself if you want to.\n" msgstr "" "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n" -"med \"%c\" kommer behÃ¥llas; du kan själv ta bort dem om du vill.\n" +"med â€%c†kommer behÃ¥llas; du kan själv ta bort dem om du vill.\n" #, c-format msgid "" @@ -4696,7 +4695,7 @@ msgid "" "An empty message aborts the commit.\n" msgstr "" "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n" -"med \"%c\" kommer behÃ¥llas; du kan själv ta bort dem om du vill.\n" +"med â€%c†kommer behÃ¥llas; du kan själv ta bort dem om du vill.\n" "Ett tomt meddelande avbryter incheckningen.\n" msgid "" @@ -4757,11 +4756,11 @@ msgstr "" #, c-format msgid "Invalid ignored mode '%s'" -msgstr "Ogiltigt ignorerat läge \"%s\"" +msgstr "Ogiltigt ignorerat läge â€%sâ€" #, c-format msgid "Invalid untracked files mode '%s'" -msgstr "Ogiltigt läge för ospÃ¥rade filer: \"%s\"" +msgstr "Ogiltigt läge för ospÃ¥rade filer: â€%sâ€" msgid "You are in the middle of a merge -- cannot reword." msgstr "Du är i mitten av en sammanslagning -- kan inte omformulera." @@ -4772,11 +4771,11 @@ msgstr "Du är i mitten av en cherry-pick -- kan inte omformulera." #, c-format msgid "reword option of '%s' and path '%s' cannot be used together" msgstr "" -"reword-flaggan till \"%s\" och sökvägen \"%s\" kan inte användas tillsammans" +"reword-flaggan till â€%s†och sökvägen â€%s†kan inte användas tillsammans" #, c-format msgid "reword option of '%s' and '%s' cannot be used together" -msgstr "reword-flaggan till \"%s\" och \"%s\" kan inte användas tillsammans" +msgstr "reword-flaggan till â€%s†och â€%s†kan inte användas tillsammans" msgid "You have nothing to amend." msgstr "Du har inget att utöka." @@ -4799,7 +4798,7 @@ msgstr "okänd flagga: --fixup=%s:%s" #, c-format msgid "paths '%s ...' with -a does not make sense" -msgstr "sökvägarna \"%s ...\" med -a ger ingen mening" +msgstr "sökvägarna â€%s ...†med -a ger ingen mening" msgid "show status concisely" msgstr "visa koncis status" @@ -4992,13 +4991,13 @@ msgstr "Avbryter pÃ¥ grund av tom incheckningsmeddelandekropp.\n" msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" -"arkivet har uppdaterats, men kunde inte skriva filen\n" -"new_index. Kontrollera att disken inte är full och\n" +"arkivet har uppdaterats, men kunde inte skriva ny\n" +"indexfil. Kontrollera att disken inte är full och\n" "att kvoten inte har överskridits, och kör sedan\n" -"\"git restore --staged :/\" för att Ã¥terställa." +"â€git restore --staged :/†för att Ã¥terställa." msgid "git config [<options>]" msgstr "git config [<flaggor>]" @@ -5071,7 +5070,7 @@ msgid "list all" msgstr "visa alla" msgid "use string equality when comparing values to 'value-pattern'" -msgstr "använd stränglikhet vid när värden jämförs med \"värde-mönster\"" +msgstr "använd stränglikhet vid när värden jämförs med â€värde-mönsterâ€" msgid "open an editor" msgstr "öppna textredigeringsprogram" @@ -5092,7 +5091,7 @@ msgid "value is given this type" msgstr "värdet har givits denna typ" msgid "value is \"true\" or \"false\"" -msgstr "värdet är \"true\" eller \"false\"" +msgstr "värdet är â€true†eller â€falseâ€" msgid "value is decimal number" msgstr "värdet är ett decimalt tal" @@ -5157,7 +5156,7 @@ msgstr "misslyckades formatera standardkonfigurationsvärde: %s" #, c-format msgid "cannot parse color '%s'" -msgstr "kan inte tolka färgen \"%s\"" +msgstr "kan inte tolka färgen â€%sâ€" msgid "unable to parse default color value" msgstr "kan inte tolka standardfärgvärde" @@ -5207,7 +5206,7 @@ msgid "" msgstr "" "--worktree kan inte användas med flera arbetskataloger om inte\n" "konfigurationsutöknignen worktreeConfig har aktiverats. Läsa stycket\n" -"\"KONFIGURATIONSFIL\" i \"git help worktree\" för detaljer" +"â€KONFIGURATIONSFIL†i â€git help worktree†för detaljer" msgid "--get-color and variable type are incoherent" msgstr "--get-color och variabeltyp stämmer inte överens" @@ -5228,11 +5227,11 @@ msgid "--default is only applicable to --get" msgstr "--default gäller bara för --get" msgid "--fixed-value only applies with 'value-pattern'" -msgstr "--fixed-value gäller endast med \"värde-mönster\"" +msgstr "--fixed-value gäller endast med â€värde-mönsterâ€" #, c-format msgid "unable to read config file '%s'" -msgstr "kan inte konfigurationsfil \"%s\"" +msgstr "kan inte läsa konfigurationsfilen â€%sâ€" msgid "error processing config file(s)" msgstr "fel vid hantering av konfigurationsfil(er)" @@ -5245,7 +5244,7 @@ msgstr "redigering av blobbar stöds ej" #, c-format msgid "cannot create configuration file %s" -msgstr "kan inte skapa konfigurationsfilen \"%s\"" +msgstr "kan inte skapa konfigurationsfilen â€%sâ€" #, c-format msgid "" @@ -5278,11 +5277,10 @@ msgid "print debugging messages to stderr" msgstr "skriv felsökningsmeddelanden pÃ¥ standard fel" msgid "credential-cache--daemon unavailable; no unix socket support" -msgstr "" -"\"credential-cache--daemon\" ej tillgänglig; stöd för unix-uttag saknas" +msgstr "â€credential-cache--daemon†ej tillgänglig; stöd för unix-uttag saknas" msgid "credential-cache unavailable; no unix socket support" -msgstr "\"credential-cache\" ej tillgänglig; stöd för unix-uttag saknas" +msgstr "â€credential-cache†ej tillgänglig; stöd för unix-uttag saknas" #, c-format msgid "unable to get credential storage lock in %d ms" @@ -5317,11 +5315,11 @@ msgstr "den annoterade taggen %s inte tillgänglig" #, c-format msgid "tag '%s' is externally known as '%s'" -msgstr "taggen \"%s\" är utanför känd som \"%s\"" +msgstr "taggen â€%s†är utanför känd som â€%sâ€" #, c-format msgid "no tag exactly matches '%s'" -msgstr "ingen tagg motsvarar \"%s\" exakt" +msgstr "ingen tagg motsvarar â€%s†exakt" #, c-format msgid "No exact match on refs or tags, searching to describe\n" @@ -5337,7 +5335,7 @@ msgid "" "No annotated tags can describe '%s'.\n" "However, there were unannotated tags: try --tags." msgstr "" -"Inga annoterade taggar kan beskriva \"%s\".\n" +"Inga annoterade taggar kan beskriva â€%sâ€.\n" "Det finns dock oannoterade taggar: testa --tags." #, c-format @@ -5345,7 +5343,7 @@ msgid "" "No tags can describe '%s'.\n" "Try --always, or create some tags." msgstr "" -"Inga taggar kan beskriva \"%s\".\n" +"Inga taggar kan beskriva â€%sâ€.\n" "Testa --always, eller skapa nÃ¥gra taggar." #, c-format @@ -5409,17 +5407,17 @@ msgid "mark" msgstr "märke" msgid "append <mark> on dirty working tree (default: \"-dirty\")" -msgstr "lägg till <märke> pÃ¥ lortigt arbetsträd (standard: \"-dirty\")" +msgstr "lägg till <märke> pÃ¥ lortigt arbetsträd (standard: â€-dirtyâ€)" msgid "append <mark> on broken working tree (default: \"-broken\")" -msgstr "lägg till <märke> pÃ¥ trasigt arbetsträd (standard: \"-broken\")" +msgstr "lägg till <märke> pÃ¥ trasigt arbetsträd (standard: â€-brokenâ€)" msgid "No names found, cannot describe anything." msgstr "Inga namn hittades, kan inte beskriva nÃ¥got." #, c-format msgid "option '%s' and commit-ishes cannot be used together" -msgstr "flaggorna \"%s\" och incheckning-igter kan inte användas samtidigt" +msgstr "flaggorna â€%s†och incheckning-igter kan inte användas samtidigt" msgid "" "git diagnose [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n" @@ -5443,7 +5441,7 @@ msgstr "--merge-base fungerar endast med tvÃ¥ incheckningar" #, c-format msgid "'%s': not a regular file or symlink" -msgstr "\"%s\": inte en normal fil eller symbolisk länk" +msgstr "â€%sâ€: inte en normal fil eller symbolisk länk" msgid "no merge given, only parents." msgstr "ingen sammanslagning angiven, endast föräldrar." @@ -5461,15 +5459,15 @@ msgstr "Inte ett git-arkiv" #, c-format msgid "invalid object '%s' given." -msgstr "objektet \"%s\" som angavs är felaktigt." +msgstr "objektet â€%s†som angavs är felaktigt." #, c-format msgid "more than two blobs given: '%s'" -msgstr "mer än tvÃ¥ blobbar angavs: \"%s\"" +msgstr "mer än tvÃ¥ blobbar angavs: â€%sâ€" #, c-format msgid "unhandled object '%s' given." -msgstr "ej hanterat objekt \"%s\" angavs." +msgstr "ej hanterat objekt â€%s†angavs." #, c-format msgid "%s...%s: multiple merge bases, using %s" @@ -5495,23 +5493,23 @@ msgid "" "combined diff formats ('-c' and '--cc') are not supported in\n" "directory diff mode ('-d' and '--dir-diff')." msgstr "" -"kombinerade diff-format (\"-c\" och \"--cc\") stöds inte i\n" -"katalogdiffläge (\"-d\" och \"--dir-diff\")." +"kombinerade diff-format (â€-c†och â€--ccâ€) stöds inte i\n" +"katalogdiffläge (â€-d†och â€--dir-diffâ€)." #, c-format msgid "both files modified: '%s' and '%s'." -msgstr "bägge filerna ändrade: \"%s\" och \"%s\"." +msgstr "bägge filerna ändrade: â€%s†och â€%sâ€." msgid "working tree file has been left." msgstr "filen i arbetskatalogen lämnades kvar." #, c-format msgid "could not copy '%s' to '%s'" -msgstr "kunde inte kopiera in \"%s\" till \"%s\"" +msgstr "kunde inte kopiera in â€%s†till â€%sâ€" #, c-format msgid "temporary files exist in '%s'." -msgstr "temporära filer finns i \"%s\"." +msgstr "temporära filer finns i â€%sâ€." msgid "you may want to cleanup or recover these." msgstr "du kanske vill städa eller rädda dem." @@ -5521,7 +5519,7 @@ msgid "failed: %d" msgstr "misslyckades: %d" msgid "use `diff.guitool` instead of `diff.tool`" -msgstr "använd \"diff.guitool\" istället för \"diff.tool\"" +msgstr "använd â€diff.guitool†istället för â€diff.toolâ€" msgid "perform a full-directory diff" msgstr "utför diff för hela katalogen" @@ -5539,20 +5537,20 @@ msgid "use the specified diff tool" msgstr "använd angivet diff-verktyg" msgid "print a list of diff tools that may be used with `--tool`" -msgstr "visa en lista över diff-verktyg som kan användas med \"--tool\"" +msgstr "visa en lista över diff-verktyg som kan användas med â€--toolâ€" msgid "" "make 'git-difftool' exit when an invoked diff tool returns a non-zero exit " "code" msgstr "" -"lÃ¥t \"git-difftool\" avsluta när ett anropat diff-verktyg ger returvärde " -"skilt frÃ¥n noll" +"lÃ¥t â€git-difftool†avsluta när ett anropat diff-verktyg ger returvärde skilt " +"frÃ¥n noll" msgid "specify a custom command for viewing diffs" msgstr "ange eget kommando för att visa diffar" msgid "passed to `diff`" -msgstr "sändes till \"diff\"" +msgstr "sändes till â€diffâ€" msgid "difftool requires worktree or --no-index" msgstr "difftool kräver en arbetskatalog eller --no-index" @@ -5631,26 +5629,26 @@ msgstr "märk taggar med märke-id" #, c-format msgid "Missing from marks for submodule '%s'" -msgstr "Saknar frÃ¥n-märken för undermodulen \"%s\"" +msgstr "Saknar frÃ¥n-märken för undermodulen â€%sâ€" #, c-format msgid "Missing to marks for submodule '%s'" -msgstr "Saknar till-märken för undermodulen \"%s\"" +msgstr "Saknar till-märken för undermodulen â€%sâ€" #, c-format msgid "Expected 'mark' command, got %s" -msgstr "Förväntade \"mark\"-kommando, fick %s" +msgstr "Förväntade â€markâ€-kommando, fick %s" #, c-format msgid "Expected 'to' command, got %s" -msgstr "Förväntade \"to\"-kommando, fick %s" +msgstr "Förväntade â€toâ€-kommando, fick %s" msgid "Expected format name:filename for submodule rewrite option" msgstr "Förvändae formatet namn:filnamn för undermodul-omskrivningsflaggan" #, c-format msgid "feature '%s' forbidden in input without --allow-unsafe-features" -msgstr "funktionen \"%s\" förbjuden i indata utan --allow-unsafe-features" +msgstr "funktionen â€%s†förbjuden i indata utan --allow-unsafe-features" #, c-format msgid "Lockfile created but not reported: %s" @@ -5717,7 +5715,7 @@ msgstr "ej snabbspolad" #, c-format msgid "cannot open '%s'" -msgstr "kan inte öppna \"%s\"" +msgstr "kan inte öppna â€%sâ€" msgid "" "fetch normally indicates which branches had a forced update,\n" @@ -5726,8 +5724,8 @@ msgid "" msgstr "" "fetch visar normalt vilka grenar som tvÃ¥ngsuppdaterats, men testet har " "slagits\n" -"av; för att slÃ¥ pÃ¥ igen, använd flaggan \"--show-forced-updates\" eller kör\n" -"\"git config fetch.showForcedUpdates true\"" +"av; för att slÃ¥ pÃ¥ igen, använd flaggan â€--show-forced-updates†eller kör\n" +"â€git config fetch.showForcedUpdates trueâ€" #, c-format msgid "" @@ -5737,9 +5735,8 @@ msgid "" "to avoid this check\n" msgstr "" "det tog %.2f sekunder att se efter tvÃ¥ngsuppdateringar; Du kan använda\n" -"\"--no-show-forced-updates\" eller köra \"git config fetch." -"showForcedUpdates\n" -"false\" för att undvika testet\n" +"â€--no-show-forced-updates†eller köra â€git config fetch.showForcedUpdates\n" +"false†för att undvika testet\n" #, c-format msgid "%s did not send all necessary objects\n" @@ -5755,7 +5752,7 @@ msgid "" " 'git remote prune %s' to remove any old, conflicting branches" msgstr "" "vissa lokala referenser kunde inte uppdateras; testa att köra\n" -" \"git remote prune %s\" för att ta bort gamla grenar som stÃ¥r i konflikt" +" â€git remote prune %s†för att ta bort gamla grenar som stÃ¥r i konflikt" #, c-format msgid " (%s will become dangling)" @@ -5773,15 +5770,15 @@ msgstr "(ingen)" #, c-format msgid "refusing to fetch into branch '%s' checked out at '%s'" -msgstr "vägrar hämta till grenen \"%s\" som är utcheckad pÃ¥ \"%s\"" +msgstr "vägrar hämta till grenen â€%s†som är utcheckad pÃ¥ â€%sâ€" #, c-format msgid "option \"%s\" value \"%s\" is not valid for %s" -msgstr "flaggan \"%s\" med värdet \"%s\" är inte giltigt för %s" +msgstr "flaggan â€%s†med värdet â€%s†är inte giltigt för %s" #, c-format msgid "option \"%s\" is ignored for %s\n" -msgstr "flaggan \"%s\" ignoreras för %s\n" +msgstr "flaggan â€%s†ignoreras för %s\n" #, c-format msgid "%s is not a valid object" @@ -5799,8 +5796,8 @@ msgid "" "could not set upstream of HEAD to '%s' from '%s' when it does not point to " "any branch." msgstr "" -"kunde inte sätta uppström för HEAD till \"%s\" frÃ¥n \"%s\" när det inte " -"pekar mot nÃ¥gon gren." +"kunde inte sätta uppström för HEAD till â€%s†frÃ¥n â€%s†när det inte pekar " +"mot nÃ¥gon gren." msgid "not setting upstream for a remote remote-tracking branch" msgstr "ställer inte in uppströmsgren för en fjärrspÃ¥rande gren pÃ¥ fjärren" @@ -5828,7 +5825,7 @@ msgstr "kunde inte hämta %s" #, c-format msgid "could not fetch '%s' (exit code: %d)\n" -msgstr "kunde inte hämta \"%s\" (felkod: %d)\n" +msgstr "kunde inte hämta â€%s†(felkod: %d)\n" msgid "" "no remote repository specified; please specify either a URL or a\n" @@ -5926,7 +5923,7 @@ msgid "refmap" msgstr "referenskarta" msgid "specify fetch refmap" -msgstr "ange referenskarta för \"fetch\"" +msgstr "ange referenskarta för â€fetchâ€" msgid "report that we have only objects reachable from this object" msgstr "rapportera att vi bara har objekt nÃ¥bara frÃ¥n detta objektet" @@ -5935,7 +5932,7 @@ msgid "do not fetch a packfile; instead, print ancestors of negotiation tips" msgstr "hämta inte paketfil; skriv istället förfäder till förhandlingstips" msgid "run 'maintenance --auto' after fetching" -msgstr "kör \"maintenance --auto\" efter hämtning" +msgstr "kör â€maintenance --auto†efter hämtning" msgid "check for forced-updates on all updated branches" msgstr "se efter tvingade uppdateringar i alla uppdaterade grenar" @@ -5957,7 +5954,7 @@ msgstr "--unshallow kan inte användas pÃ¥ ett komplett arkiv" #, c-format msgid "failed to fetch bundles from '%s'" -msgstr "misslyckades hämta buntar frÃ¥n \"%s\"" +msgstr "misslyckades hämta buntar frÃ¥n â€%sâ€" msgid "fetch --all does not take a repository argument" msgstr "fetch --all tar inte namnet pÃ¥ ett arkiv som argument" @@ -6133,11 +6130,11 @@ msgstr "kunde inte skapa lost-found" #, c-format msgid "could not write '%s'" -msgstr "kunde inte skriva \"%s\"" +msgstr "kunde inte skriva â€%sâ€" #, c-format msgid "could not finish '%s'" -msgstr "kunde inte avsluta \"%s\"" +msgstr "kunde inte avsluta â€%sâ€" #, c-format msgid "Checking %s" @@ -6174,7 +6171,7 @@ msgstr "%s: ogiltig reflog-post %s" #, c-format msgid "Checking reflog %s->%s" -msgstr "Kontrollerar reflog %s->%s" +msgstr "Kontrollerar reflog %s→%s" #, c-format msgid "%s: invalid sha1 pointer %s" @@ -6197,7 +6194,7 @@ msgstr "%s: objektet trasigt eller saknas: %s" #, c-format msgid "%s: object is of unknown type '%s': %s" -msgstr "%s: objektet har okänd typ \"%s\": %s" +msgstr "%s: objektet har okänd typ â€%sâ€: %s" #, c-format msgid "%s: object could not be parsed: %s" @@ -6250,11 +6247,11 @@ msgstr "%s: ogiltig sha1-pekare i resolve-undo för %s" #, c-format msgid "unable to load rev-index for pack '%s'" -msgstr "kunde inte läsa rev-index för paketfil \"%s\"" +msgstr "kunde inte läsa rev-index för paketfil â€%sâ€" #, c-format msgid "invalid rev-index for pack '%s'" -msgstr "ogiltigt rev-index för paketet \"%s\"" +msgstr "ogiltigt rev-index för paketet â€%sâ€" msgid "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" @@ -6314,7 +6311,7 @@ msgstr "%s: objekt saknas" #, c-format msgid "invalid parameter: expected sha1, got '%s'" -msgstr "ogiltig parameter: förväntade sha1, fick \"%s\"" +msgstr "ogiltig parameter: förväntade sha1, fick â€%sâ€" msgid "git fsmonitor--daemon start [<options>]" msgstr "git fsmonitor--daemon start [<flaggor>]" @@ -6324,23 +6321,23 @@ msgstr "git fsmonitor--daemon run [<flaggor>]" #, c-format msgid "value of '%s' out of range: %d" -msgstr "värdet för \"%s\" utanför intervallet: %d" +msgstr "värdet för â€%s†utanför intervallet: %d" #, c-format msgid "value of '%s' not bool or int: %d" -msgstr "värdet för \"%s\" är inte bool eller int: %d" +msgstr "värdet för â€%s†är inte bool eller int: %d" #, c-format msgid "fsmonitor-daemon is watching '%s'\n" -msgstr "fsmonitor-daemon bevakar \"%s\"\n" +msgstr "fsmonitor-daemon bevakar â€%sâ€\n" #, c-format msgid "fsmonitor-daemon is not watching '%s'\n" -msgstr "fsmonitor-daemon bevakar inte \"%s\"\n" +msgstr "fsmonitor-daemon bevakar inte â€%sâ€\n" #, c-format msgid "could not create fsmonitor cookie '%s'" -msgstr "kunde inte skapa fsmonitor-kaka \"%s\"" +msgstr "kunde inte skapa fsmonitor-kaka â€%sâ€" #, c-format msgid "fsmonitor: cookie_result '%d' != SEEN" @@ -6348,7 +6345,7 @@ msgstr "fsmonitor: cookie_result '%d' != SEEN" #, c-format msgid "could not start IPC thread pool on '%s'" -msgstr "kunde inte starta IPC-trÃ¥dpol pÃ¥ \"%s\"" +msgstr "kunde inte starta IPC-trÃ¥dpol pÃ¥ â€%sâ€" msgid "could not start fsmonitor listener thread" msgstr "kunde inte starta fsmonitor-lyssnartrÃ¥d" @@ -6364,19 +6361,19 @@ msgstr "kunde inte initiera hälsotrÃ¥d" #, c-format msgid "could not cd home '%s'" -msgstr "kunde inte byta katalog hem \"%s\"" +msgstr "kunde inte byta katalog hem â€%sâ€" #, c-format msgid "fsmonitor--daemon is already running '%s'" -msgstr "fsmonitor--daemon körs redan pÃ¥ \"%s\"" +msgstr "fsmonitor--daemon körs redan pÃ¥ â€%sâ€" #, c-format msgid "running fsmonitor-daemon in '%s'\n" -msgstr "kör fsmonitor-daemon i \"%s\"\n" +msgstr "kör fsmonitor-daemon i â€%sâ€\n" #, c-format msgid "starting fsmonitor-daemon in '%s'\n" -msgstr "startar fsmonitor-daemon i \"%s\"\n" +msgstr "startar fsmonitor-daemon i â€%sâ€\n" msgid "daemon failed to start" msgstr "serverprocessen kunde inte startas" @@ -6398,11 +6395,11 @@ msgstr "max sekunder att vänta pÃ¥ att serverprocessen startar" #, c-format msgid "invalid 'ipc-threads' value (%d)" -msgstr "ogiltigt värde för \"ipc-threads\" (%d)" +msgstr "ogiltigt värde för â€ipc-threads†(%d)" #, c-format msgid "Unhandled subcommand '%s'" -msgstr "Ej hanterat underkommando \"%s\"" +msgstr "Ej hanterat underkommando â€%sâ€" msgid "fsmonitor--daemon not supported on this platform" msgstr "fsmonitor--daemon stöds inte pÃ¥ denna plattform" @@ -6416,11 +6413,11 @@ msgstr "Misslyckades ta status (fstat) pÃ¥ %s: %s" #, c-format msgid "failed to parse '%s' value '%s'" -msgstr "misslyckades tolka \"%s\" värde \"%s\"" +msgstr "misslyckades tolka â€%s†värde â€%sâ€" #, c-format msgid "cannot stat '%s'" -msgstr "kan inte ta status pÃ¥ \"%s\"" +msgstr "kan inte ta status pÃ¥ â€%sâ€" #, c-format msgid "" @@ -6442,6 +6439,9 @@ msgstr "rensa ej refererade objekt" msgid "pack unreferenced objects separately" msgstr "packa ej refererade objekt separat" +msgid "with --cruft, limit the size of new cruft packs" +msgstr "med --cruft, begränsa storleken pÃ¥ nya onödiga paket" + msgid "be more thorough (increased runtime)" msgstr "var mer grundlig (ökar körtiden)" @@ -6472,20 +6472,19 @@ msgstr "Packar arkivet automatiskt för optimal prestanda.\n" #, c-format msgid "See \"git help gc\" for manual housekeeping.\n" -msgstr "Se \"git help gc\" för manuell hushÃ¥llning.\n" +msgstr "Se â€git help gc†för manuell hushÃ¥llning.\n" #, c-format msgid "" "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)" msgstr "" -"gc körs redan pÃ¥ maskinen \"%s\" pid %<PRIuMAX> (använd --force om sÃ¥ inte " -"är fallet)" +"gc körs redan pÃ¥ maskinen â€%s†pid %<PRIuMAX> (använd --force om sÃ¥ inte är " +"fallet)" msgid "" "There are too many unreachable loose objects; run 'git prune' to remove them." msgstr "" -"Det finns för mÃ¥nga onÃ¥bara lösa objekt; kör \"git prune\" för att ta bort " -"dem." +"Det finns för mÃ¥nga onÃ¥bara lösa objekt; kör â€git prune†för att ta bort dem." msgid "" "git maintenance run [--auto] [--[no-]quiet] [--task=<task>] [--schedule]" @@ -6506,41 +6505,41 @@ msgid "failed to prefetch remotes" msgstr "kunde inte förhämta fjärrar" msgid "failed to start 'git pack-objects' process" -msgstr "kunde inte starta \"git pack-objects\"-process" +msgstr "kunde inte starta â€git pack-objectsâ€-process" msgid "failed to finish 'git pack-objects' process" -msgstr "kunde inte avsluta \"git pack-objects\"-process" +msgstr "kunde inte avsluta â€git pack-objectsâ€-process" msgid "failed to write multi-pack-index" msgstr "kunde inte skriva multi-pack-index" msgid "'git multi-pack-index expire' failed" -msgstr "\"git multi-pack-index expire\" misslyckades" +msgstr "â€git multi-pack-index expire†misslyckades" msgid "'git multi-pack-index repack' failed" -msgstr "\"git multi-pack-index repack\" misslyckades" +msgstr "â€git multi-pack-index repack†misslyckades" msgid "" "skipping incremental-repack task because core.multiPackIndex is disabled" msgstr "" -"hoppar över \"incremental-repack\"-uppgift eftersom core.multiPackIndex är " +"hoppar över â€incremental-repackâ€-uppgift eftersom core.multiPackIndex är " "inaktiverat" #, c-format msgid "lock file '%s' exists, skipping maintenance" -msgstr "lÃ¥sfilen \"%s\" finns, hoppar över underhÃ¥ll" +msgstr "lÃ¥sfilen â€%s†finns, hoppar över underhÃ¥ll" #, c-format msgid "task '%s' failed" -msgstr "uppgiften \"%s\" misslyckades" +msgstr "uppgiften â€%s†misslyckades" #, c-format msgid "'%s' is not a valid task" -msgstr "\"%s\" är inte en giltig uppgift" +msgstr "â€%s†är inte en giltig uppgift" #, c-format msgid "task '%s' cannot be selected multiple times" -msgstr "uppgiften \"%s\" kan inte väljas flera gÃ¥nger" +msgstr "uppgiften â€%s†kan inte väljas flera gÃ¥nger" msgid "run tasks based on the state of the repository" msgstr "kör uppgifter baserad pÃ¥ arkivets tillstÃ¥nd" @@ -6565,29 +6564,29 @@ msgstr "använd som mest en av --auto och --schedule=<frekvens>" #, c-format msgid "unable to add '%s' value of '%s'" -msgstr "kan inte lägga till \"%s\"-värdet för \"%s\"" +msgstr "kan inte lägga till â€%sâ€-värdet för â€%sâ€" msgid "return success even if repository was not registered" msgstr "returnera framgÃ¥ng även om arkivet inte var registrerat" #, c-format msgid "unable to unset '%s' value of '%s'" -msgstr "kan inte ta bort \"%s\"-värdet för \"%s\"" +msgstr "kan inte ta bort â€%sâ€-värdet för â€%sâ€" #, c-format msgid "repository '%s' is not registered" -msgstr "arkivet \"%s\" har inte registrerats" +msgstr "arkivet â€%s†har inte registrerats" #, c-format msgid "failed to expand path '%s'" -msgstr "misslyckades expandera sökvägen \"%s\"" +msgstr "misslyckades expandera sökvägen â€%sâ€" msgid "failed to start launchctl" msgstr "misslyckades starta launchctl" #, c-format msgid "failed to create directories for '%s'" -msgstr "misslyckades skapa kataloger för \"%s\"" +msgstr "misslyckades skapa kataloger för â€%sâ€" #, c-format msgid "failed to bootstrap service %s" @@ -6600,8 +6599,7 @@ msgid "failed to start schtasks" msgstr "misslyckades starta schtasks" msgid "failed to run 'crontab -l'; your system might not support 'cron'" -msgstr "" -"misslyckades köra \"crontab -l\"; ditt system kanske inte stöder \"cron\"" +msgstr "misslyckades köra â€crontab -lâ€; ditt system kanske inte stöder â€cronâ€" msgid "failed to create crontab temporary file" msgstr "misslyckades skapa temporär crontab-fil" @@ -6610,28 +6608,28 @@ msgid "failed to open temporary file" msgstr "misslyckades öppna temporär fil" msgid "failed to run 'crontab'; your system might not support 'cron'" -msgstr "misslyckades köra \"crontab\"; ditt system kanske inte stöder \"cron\"" +msgstr "misslyckades köra â€crontabâ€; ditt system kanske inte stöder â€cronâ€" msgid "'crontab' died" -msgstr "\"crontab\" dog" - -msgid "failed to start systemctl" -msgstr "misslyckades starta systemctl" - -msgid "failed to run systemctl" -msgstr "misslyckades att köra systemctl" +msgstr "â€crontab†dog" #, c-format msgid "failed to delete '%s'" -msgstr "misslyckades ta bort \"%s\"" +msgstr "misslyckades ta bort â€%sâ€" #, c-format msgid "failed to flush '%s'" -msgstr "misslyckades spola \"%s\"" +msgstr "misslyckades spola â€%sâ€" + +msgid "failed to start systemctl" +msgstr "misslyckades starta systemctl" + +msgid "failed to run systemctl" +msgstr "misslyckades att köra systemctl" #, c-format msgid "unrecognized --scheduler argument '%s'" -msgstr "okänt argument för --scheduler, \"%s\"" +msgstr "okänt argument för --scheduler, â€%sâ€" msgid "neither systemd timers nor crontab are available" msgstr "varken systemd-timer eller crontab är tillgänglig" @@ -6650,7 +6648,10 @@ msgid "scheduler" msgstr "schemaläggare" msgid "scheduler to trigger git maintenance run" -msgstr "schemaläggare som utlöser \"git maintenance\"-körning" +msgstr "schemaläggare som utlöser â€git maintenanceâ€-körning" + +msgid "failed to set up maintenance schedule" +msgstr "misslyckades uppdatera underhÃ¥llsschema" msgid "failed to add repo to global config" msgstr "misslyckades lägga till arkiv till global konfiguration" @@ -6683,12 +6684,16 @@ msgid "unable to read tree (%s)" msgstr "kunde inte läsa träd (%s)" #, c-format +msgid "unable to read tree %s" +msgstr "kunde inte läsa trädet %s" + +#, c-format msgid "unable to grep from object of type %s" -msgstr "kunde inte \"grep\" frÃ¥n objekt av typen %s" +msgstr "kunde inte â€grep†frÃ¥n objekt av typen %s" #, c-format msgid "switch `%c' expects a numerical value" -msgstr "flaggan \"%c\" antar ett numeriskt värde" +msgstr "flaggan â€%c†antar ett numeriskt värde" msgid "search in index instead of in the work tree" msgstr "sök i indexet istället för i arbetskatalogen" @@ -6700,7 +6705,7 @@ msgid "search in both tracked and untracked files" msgstr "sök i bÃ¥de spÃ¥rade och ospÃ¥rade filer" msgid "ignore files specified via '.gitignore'" -msgstr "ignorera filer angivna i \".gitignore\"" +msgstr "ignorera filer angivna i â€.gitignoreâ€" msgid "recursively search in each submodule" msgstr "sök varje undermodul rekursivt" @@ -6726,8 +6731,8 @@ msgstr "hantera binärfiler med textconv-filter" msgid "search in subdirectories (default)" msgstr "sök i underkataloger (standard)" -msgid "descend at most <depth> levels" -msgstr "gÃ¥ som mest ned <djup> nivÃ¥er" +msgid "descend at most <n> levels" +msgstr "gÃ¥ som mest ned <n> nivÃ¥er" msgid "use extended POSIX regular expressions" msgstr "använd utökade POSIX-reguljära uttryck" @@ -6934,7 +6939,7 @@ msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<kommando>|<doc>]" #, c-format msgid "unrecognized help format '%s'" -msgstr "okänt hjälpformat: \"%s\"" +msgstr "okänt hjälpformat: â€%sâ€" msgid "Failed to start emacsclient." msgstr "Misslyckades starta emacsclient." @@ -6944,31 +6949,31 @@ msgstr "Kunde inte tolka emacsclient-version." #, c-format msgid "emacsclient version '%d' too old (< 22)." -msgstr "emacsclient version \"%d\" för gammal (< 22)." +msgstr "emacsclient version â€%d†för gammal (< 22)." #, c-format msgid "failed to exec '%s'" -msgstr "exec misslyckades för \"%s\"" +msgstr "exec misslyckades för â€%sâ€" #, c-format msgid "" "'%s': path for unsupported man viewer.\n" "Please consider using 'man.<tool>.cmd' instead." msgstr "" -"\"%s\": sökväg för man-visare som ej stöds.\n" -"Använd \"man.<verktyg>.cmd\" istället." +"â€%sâ€: sökväg för man-visare som ej stöds.\n" +"Använd â€man.<verktyg>.cmd†istället." #, c-format msgid "" "'%s': cmd for supported man viewer.\n" "Please consider using 'man.<tool>.path' instead." msgstr "" -"\"%s\": kommando för man-visare som stöds.\n" -"Använd \"man.<verktyg>.path\" istället." +"â€%sâ€: kommando för man-visare som stöds.\n" +"Använd â€man.<verktyg>.path†istället." #, c-format msgid "'%s': unknown man viewer." -msgstr "\"%s\": okänd man-visare." +msgstr "â€%sâ€: okänd man-visare." msgid "no man viewer handled the request" msgstr "ingen man-visare hanterade förfrÃ¥gan" @@ -6978,7 +6983,7 @@ msgstr "ingen info-visare hanterade förfrÃ¥gan" #, c-format msgid "'%s' is aliased to '%s'" -msgstr "\"%s\" är ett alias för \"%s\"" +msgstr "â€%s†är ett alias för â€%sâ€" #, c-format msgid "bad alias.%s string: %s" @@ -6986,20 +6991,19 @@ msgstr "felaktig alias.%s-sträng: %s" #, c-format msgid "the '%s' option doesn't take any non-option arguments" -msgstr "flaggan \"%s\" tar inte nÃ¥gra argument som inte är flaggor" +msgstr "flaggan â€%s†tar inte nÃ¥gra argument som inte är flaggor" msgid "" "the '--no-[external-commands|aliases]' options can only be used with '--all'" msgstr "" -"flaggorna '--no-[external-commands|aliases]' kan endast användas med \"--all" -"\"" +"flaggorna '--no-[external-commands|aliases]' kan endast användas med â€--allâ€" #, c-format msgid "usage: %s%s" msgstr "användning: %s%s" msgid "'git help config' for more information" -msgstr "\"git help config\" för mer information" +msgstr "â€git help config†för mer information" msgid "" "git hook run [--ignore-missing] [--to-stdin=<path>] <hook-name> [-- <hook-" @@ -7074,7 +7078,7 @@ msgid "unknown object type %d" msgstr "okänd objekttyp %d" msgid "cannot pread pack file" -msgstr "kan inte utföra \"pread\" pÃ¥ paketfil" +msgstr "kan inte utföra â€pread†pÃ¥ paketfil" #, c-format msgid "premature end of pack file, %<PRIuMAX> byte missing" @@ -7090,10 +7094,6 @@ msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "SHA1-KOLLISION UPPTÄCKT VID %s !" #, c-format -msgid "unable to read %s" -msgstr "kunde inte läsa %s" - -#, c-format msgid "cannot read existing object info %s" msgstr "kan inte läsa information om befintligt objekt %s" @@ -7125,7 +7125,7 @@ msgid "pack is corrupted (SHA1 mismatch)" msgstr "paketet är trasigt (SHA1 stämmer inte)" msgid "cannot fstat packfile" -msgstr "kan inte utföra \"fstat\" pÃ¥ paketfil" +msgstr "kan inte utföra â€fstat†pÃ¥ paketfil" msgid "pack has junk at the end" msgstr "paket har skräp i slutet" @@ -7161,7 +7161,7 @@ msgstr[1] "paketet har %d oanalyserade delta" #, c-format msgid "unable to deflate appended object (%d)" -msgstr "kunde inte utföra \"deflate\" pÃ¥ tillagt objekt (%d)" +msgstr "kunde inte utföra â€deflate†pÃ¥ tillagt objekt (%d)" #, c-format msgid "local object %s is corrupt" @@ -7169,19 +7169,19 @@ msgstr "lokalt objekt %s är trasigt" #, c-format msgid "packfile name '%s' does not end with '.%s'" -msgstr "paketfilnamnet \"%s\" slutar inte med \".%s\"" +msgstr "paketfilnamnet â€%s†slutar inte med â€.%sâ€" #, c-format msgid "cannot write %s file '%s'" -msgstr "kan inte ta skriva %s-fil \"%s\"" +msgstr "kan inte ta skriva %s-fil â€%sâ€" #, c-format msgid "cannot close written %s file '%s'" -msgstr "kan inte stänga skriven %s-fil \"%s\"" +msgstr "kan inte stänga skriven %s-fil â€%sâ€" #, c-format msgid "unable to rename temporary '*.%s' file to '%s'" -msgstr "kunde inte byta namn pÃ¥ temporär \"*.%s\"-fil till \"%s\"" +msgstr "kunde inte byta namn pÃ¥ temporär â€*.%sâ€-fil till â€%sâ€" msgid "error while closing pack file" msgstr "fel vid stängning av paketfil" @@ -7192,11 +7192,11 @@ msgstr "felaktig pack.indexVersion=%<PRIu32>" #, c-format msgid "Cannot open existing pack file '%s'" -msgstr "Kan inte öppna befintlig paketfil \"%s\"" +msgstr "Kan inte öppna befintlig paketfil â€%sâ€" #, c-format msgid "Cannot open existing pack idx file for '%s'" -msgstr "Kan inte öppna befintlig paket-idx-fil för \"%s\"" +msgstr "Kan inte öppna befintlig paket-idx-fil för â€%sâ€" #, c-format msgid "non delta: %d object" @@ -7219,7 +7219,7 @@ msgstr "felaktig %s" #, c-format msgid "unknown hash algorithm '%s'" -msgstr "okänd hashningsalgoritm \"%s\"" +msgstr "okänd hashningsalgoritm â€%sâ€" msgid "--stdin requires a git repository" msgstr "--stdin kräver ett git-arkiv" @@ -7233,11 +7233,13 @@ msgstr "fsck-fel i packat objekt" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" "git init [-q | --quiet] [--bare] [--template=<mallkatalog>]\n" " [--separate-git-dir <git-kat>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <grennamn> | --initial-branch=<grennamn>]\n" " [--shared[=<behörigheter>]] [<katalog>]" @@ -7274,18 +7276,19 @@ msgstr "" #, c-format msgid "Cannot access work tree '%s'" -msgstr "Kan inte komma Ã¥t arbetskatalogen \"%s\"" +msgstr "Kan inte komma Ã¥t arbetskatalogen â€%sâ€" msgid "--separate-git-dir incompatible with bare repository" msgstr "--separate-git-dir är inkompatibelt med naket arkiv" msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <symbol>[(=|:)<värde>])...]\n" +" [(--trailer (<nyckel>|<nyckelAlias>)" +"[(=|:)<värde>])...]\n" " [--parse] [<fil>...]" msgid "edit files in place" @@ -7294,6 +7297,9 @@ msgstr "redigera filer pÃ¥ plats" msgid "trim empty trailers" msgstr "ta bort tomma släprader" +msgid "placement" +msgstr "placering" + msgid "where to place the new trailer" msgstr "var nya släprader ska placeras" @@ -7306,17 +7312,17 @@ msgstr "att göra om släprader saknas" msgid "output only the trailers" msgstr "visa endast släprader" -msgid "do not apply config rules" -msgstr "använd inte regler frÃ¥n konfigurationen" +msgid "do not apply trailer.* configuration variables" +msgstr "tillämpa inte konfigurationsvariablerna trailer.*" -msgid "join whitespace-continued values" -msgstr "slÃ¥ ihop värden avdelade med blanksteg" +msgid "reformat multiline trailer values as single-line values" +msgstr "omformatera flerradiga släpradsvärden som enradsvärden" -msgid "set parsing options" -msgstr "välj tolkningsalternativ" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "alias för --only-trailers --only-input --unfold" -msgid "do not treat --- specially" -msgstr "tolka inte --- speciellt" +msgid "do not treat \"---\" as the end of input" +msgstr "tolka inte â€---†som slut pÃ¥ indata" msgid "trailer(s) to add" msgstr "släprad(er) att lägga till" @@ -7405,6 +7411,10 @@ msgstr "behöver precis ett intervall" msgid "not a range" msgstr "inte ett intervall" +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "kan inte läsa grenbeskrivningsfilen â€%sâ€" + msgid "cover letter needs email format" msgstr "omslagsbrevet behöver e-postformat" @@ -7427,7 +7437,7 @@ msgstr "okänd incheckning %s" #, c-format msgid "failed to resolve '%s' as a valid ref" -msgstr "misslyckades slÃ¥ upp \"%s\" som en giltig referens" +msgstr "misslyckades slÃ¥ upp â€%s†som en giltig referens" msgid "could not find exact merge base" msgstr "kunde inte hitta exakt sammanslagningsbas" @@ -7458,7 +7468,7 @@ msgstr "misslyckades räkna ut intervalldiff-ursprung för aktuell serie" #, c-format msgid "using '%s' as range-diff origin of current series" -msgstr "använd \"%s\" som intervalldiff-ursprung för aktuell serie" +msgstr "använd â€%s†som intervalldiff-ursprung för aktuell serie" msgid "use [PATCH n/m] even with a single patch" msgstr "använd [PATCH n/m] även för en ensam patch" @@ -7479,7 +7489,7 @@ msgid "sfx" msgstr "sfx" msgid "use <sfx> instead of '.patch'" -msgstr "använd <sfx> istället för \".patch\"" +msgstr "använd <sfx> istället för â€.patchâ€" msgid "start numbering patches at <n> instead of 1" msgstr "börja numrera patchar pÃ¥ <n> istället för 1" @@ -7502,6 +7512,9 @@ msgstr "cover-from-description-läge" msgid "generate parts of a cover letter based on a branch's description" msgstr "skapa delar av omslagsbrevet baserat pÃ¥ grenbeskrivelsen" +msgid "use branch description from file" +msgstr "använd grenbeskrivningar frÃ¥n fil" + msgid "use [<prefix>] instead of [PATCH]" msgstr "använd [<prefix>] istället för [PATCH]" @@ -7536,10 +7549,10 @@ msgid "email" msgstr "epost" msgid "add To: header" -msgstr "lägg till mottagarhuvud (\"To:\")" +msgstr "lägg till mottagarhuvud (â€To:â€)" msgid "add Cc: header" -msgstr "lägg till kopiehuvud (\"Cc:\")" +msgstr "lägg till kopiehuvud (â€Cc:â€)" msgid "ident" msgstr "ident" @@ -7616,7 +7629,7 @@ msgstr "kan inte använda --remerge-diff" #, c-format msgid "could not create directory '%s'" -msgstr "kunde inte skapa katalogen \"%s\"" +msgstr "kunde inte skapa katalogen â€%sâ€" msgid "--interdiff requires --cover-letter or single patch" msgstr "--interdiff kräver --cover-letter eller ensam patch" @@ -7640,7 +7653,7 @@ msgstr "Intervall-diff mot v%d:" #, c-format msgid "unable to read signature file '%s'" -msgstr "kunde inte läsa signaturfil \"%s\"" +msgstr "kunde inte läsa signaturfil â€%sâ€" msgid "Generating patches" msgstr "Skapar patchar" @@ -7658,15 +7671,15 @@ msgstr "Kunde inte hitta en spÃ¥rad fjärrgren, ange <uppström> manuellt.\n" #, c-format msgid "could not get object info about '%s'" -msgstr "kunde inte hämta objektinfo om \"%s\"" +msgstr "kunde inte hämta objektinfo om â€%sâ€" #, c-format msgid "bad ls-files format: element '%s' does not start with '('" -msgstr "felaktigt ls-files-format: elementet \"%s\" börjar inte med \"(\"" +msgstr "felaktigt ls-files-format: elementet â€%s†börjar inte med â€(â€" #, c-format msgid "bad ls-files format: element '%s' does not end in ')'" -msgstr "felaktigt ls-files-format: elementet \"%s\" slutar inte med \")\"" +msgstr "felaktigt ls-files-format: elementet â€%s†slutar inte med â€)â€" #, c-format msgid "bad ls-files format: %%%.*s" @@ -7682,10 +7695,10 @@ msgid "identify the file status with tags" msgstr "identifiera filstatus med taggar" msgid "use lowercase letters for 'assume unchanged' files" -msgstr "använd smÃ¥ bokstäver för \"anta oförändrade\"-filer" +msgstr "använd smÃ¥ bokstäver för â€anta oförändradeâ€-filer" msgid "use lowercase letters for 'fsmonitor clean' files" -msgstr "använd smÃ¥ bokstäver för \"fsmonitor clean\"-filer" +msgstr "använd smÃ¥ bokstäver för â€fsmonitor cleanâ€-filer" msgid "show cached files in the output (default)" msgstr "visa cachade filer i utdata (standard)" @@ -7709,7 +7722,7 @@ msgid "show files on the filesystem that need to be removed" msgstr "visa filer i filsystemet som behöver tas bort" msgid "show 'other' directories' names only" -msgstr "visa endast namn för \"andra\" kataloger" +msgstr "visa endast namn för â€andra†kataloger" msgid "show line endings of files" msgstr "visa radslut i filer" @@ -7721,7 +7734,7 @@ msgid "show unmerged files in the output" msgstr "visa ej sammanslagna filer i utdata" msgid "show resolve-undo information" -msgstr "visa \"resolve-undo\"-information" +msgstr "visa â€resolve-undoâ€-information" msgid "skip files matching pattern" msgstr "hoppa över filer som motsvarar mönster" @@ -7804,11 +7817,11 @@ msgstr "git ls-tree [<flaggor>] <träd-igt> [<sökväg>...]" #, c-format msgid "bad ls-tree format: element '%s' does not start with '('" -msgstr "felaktigt ls-tree-format: elementet \"%s\" börjar inte med \"(\"" +msgstr "felaktigt ls-tree-format: elementet â€%s†börjar inte med â€(â€" #, c-format msgid "bad ls-tree format: element '%s' does not end in ')'" -msgstr "felaktigt ls-tree-format: elementet \"%s\" slutar inte med \")\"" +msgstr "felaktigt ls-tree-format: elementet â€%s†slutar inte med â€)â€" #, c-format msgid "bad ls-tree format: %%%.*s" @@ -7852,7 +7865,7 @@ msgid "keep subject" msgstr "behÃ¥ll ärenderad" msgid "keep non patch brackets in subject" -msgstr "behÃ¥ll hakparanterser som inte är \"patch\" i ärenderaden" +msgstr "behÃ¥ll hakparanterser som inte är â€patch†i ärenderaden" msgid "copy Message-ID to the end of commit message" msgstr "kopiera Message-ID till slutet av incheckningsmeddelandet" @@ -7886,7 +7899,7 @@ msgstr "läser patchar frÃ¥n standard in/tty..." #, c-format msgid "empty mbox: '%s'" -msgstr "tom mbox: \"%s\"" +msgstr "tom mbox: â€%sâ€" msgid "git merge-base [-a | --all] <commit> <commit>..." msgstr "git merge-base [-a | --all] <incheckning> <incheckning>..." @@ -7925,9 +7938,18 @@ msgstr "" "git merge-file [<alternativ>] [-L <namn1> [-L <orig> [-L <namn2>]]] <fil1> " "<origfil> <fil2>" +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"flaggan diff-algorithm godtar â€myersâ€, â€minimalâ€, â€patience†och â€histogramâ€" + msgid "send results to standard output" msgstr "sänd resultat till standard ut" +msgid "use object IDs instead of filenames" +msgstr "använd objekt-ID istället för filnamn" + msgid "use a diff3 based merge" msgstr "använd diff3-baserad sammanslagning" @@ -7943,6 +7965,12 @@ msgstr "för konflikter, använd deras version" msgid "for conflicts, use a union version" msgstr "för konflikter, använd en förenad version" +msgid "<algorithm>" +msgstr "<algoritm>" + +msgid "choose a diff algorithm" +msgstr "välj en diff-algoritm" + msgid "for conflicts, use this marker size" msgstr "för konflikter, använd denna markörstorlek" @@ -7953,12 +7981,19 @@ msgid "set labels for file1/orig-file/file2" msgstr "sätt etiketter för fil1/origfil/fil2" #, c-format +msgid "object '%s' does not exist" +msgstr "objektet â€%s†finns inte" + +msgid "Could not write object file" +msgstr "Kunde inte skriva objektfilen" + +#, c-format msgid "unknown option %s" msgstr "okänd flagga %s" #, c-format msgid "could not parse object '%s'" -msgstr "kunde inte tolka objektet \"%s\"" +msgstr "kunde inte tolka objektet â€%sâ€" #, c-format msgid "cannot handle more than %d base. Ignoring %s." @@ -7971,7 +8006,7 @@ msgstr "hanterar inte nÃ¥got annat än en sammanslagning av tvÃ¥ huvuden." #, c-format msgid "could not resolve ref '%s'" -msgstr "kunde inte bestämma referensen \"%s\"" +msgstr "kunde inte bestämma referensen â€%sâ€" #, c-format msgid "Merging %s with %s\n" @@ -8013,15 +8048,22 @@ msgstr "utför flera sammanslagningar, en per indatarad" msgid "specify a merge-base for the merge" msgstr "ange en sammanslagningsbas för sammanslagningen" +msgid "option=value" +msgstr "alternativ=värde" + +msgid "option for selected merge strategy" +msgstr "alternativ för vald sammanslagningsstrategi" + msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge är inkompatibelt med andra flaggor" -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base är inkompatibel med --stdin" +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "okänd strategiflagga: -X%s" #, c-format msgid "malformed input line: '%s'." -msgstr "felaktig indatarad: \"%s\"." +msgstr "felaktig indatarad: â€%sâ€." #, c-format msgid "merging cannot continue; got unclean result of %d" @@ -8031,15 +8073,15 @@ msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<flaggor>] [<incheckning>...]" msgid "switch `m' requires a value" -msgstr "flaggan \"m\" behöver ett värde" +msgstr "flaggan â€m†behöver ett värde" #, c-format msgid "option `%s' requires a value" -msgstr "flaggan \"%s\" behöver ett värde" +msgstr "flaggan â€%s†behöver ett värde" #, c-format msgid "Could not find merge strategy '%s'.\n" -msgstr "Kunde inte hitta sammanslagningsstrategin \"%s\".\n" +msgstr "Kunde inte hitta sammanslagningsstrategin â€%sâ€.\n" #, c-format msgid "Available strategies are:" @@ -8086,12 +8128,6 @@ msgstr "strategi" msgid "merge strategy to use" msgstr "sammanslagningsstrategi att använda" -msgid "option=value" -msgstr "alternativ=värde" - -msgid "option for selected merge strategy" -msgstr "alternativ för vald sammanslagningsstrategi" - msgid "merge commit message (for a non-fast-forward merge)" msgstr "incheckningsmeddelande för (icke snabbspolande) sammanslagning" @@ -8139,7 +8175,7 @@ msgstr "Inget sammanslagningsmeddelande -- uppdaterar inte HEAD\n" #, c-format msgid "'%s' does not point to a commit" -msgstr "\"%s\" verkar inte peka pÃ¥ en incheckning" +msgstr "â€%s†verkar inte peka pÃ¥ en incheckning" #, c-format msgid "Bad branch.%s.mergeoptions string: %s" @@ -8152,22 +8188,17 @@ msgid "Not handling anything other than two heads merge." msgstr "Hanterar inte nÃ¥got annat än en sammanslagning av tvÃ¥ huvuden." #, c-format -msgid "unknown strategy option: -X%s" -msgstr "okänd strategiflagga: -X%s" - -#, c-format msgid "unable to write %s" msgstr "kunde inte skriva %s" #, c-format msgid "Could not read from '%s'" -msgstr "Kunde inte läsa frÃ¥n \"%s\"" +msgstr "Kunde inte läsa frÃ¥n â€%sâ€" #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" -"Checkar inte in sammanslagningen; använd \"git commit\" för att slutföra " -"den.\n" +"Checkar inte in sammanslagningen; använd â€git commit†för att slutföra den.\n" msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -8187,7 +8218,7 @@ msgid "" "Lines starting with '%c' will be ignored, and an empty message aborts\n" "the commit.\n" msgstr "" -"Rader som inleds med \"%c\" kommer ignoreras, och ett tomt meddelande\n" +"Rader som inleds med â€%c†kommer ignoreras, och ett tomt meddelande\n" "avbryter incheckningen.\n" msgid "Empty commit message." @@ -8217,11 +8248,11 @@ msgstr "Ingen fjärrspÃ¥rande gren för %s frÃ¥n %s" #, c-format msgid "Bad value '%s' in environment '%s'" -msgstr "Felaktigt värde \"%s\" i miljövariabeln \"%s\"" +msgstr "Felaktigt värde â€%s†i miljövariabeln â€%sâ€" #, c-format msgid "could not close '%s'" -msgstr "kunde inte stänga \"%s\"" +msgstr "kunde inte stänga â€%sâ€" #, c-format msgid "not something we can merge in %s: %s" @@ -8253,11 +8284,11 @@ msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you merge." msgstr "" -"Du har inte avslutat din \"cherry-pick\" (CHERRY_PICK_HEAD finns).\n" +"Du har inte avslutat din â€cherry-pick†(CHERRY_PICK_HEAD finns).\n" "Checka in dina ändringar innan du slÃ¥r ihop." msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." -msgstr "Du har inte avslutat din \"cherry-pick\" (CHERRY_PICK_HEAD finns)." +msgstr "Du har inte avslutat din â€cherry-pick†(CHERRY_PICK_HEAD finns)." msgid "No commit specified and merge.defaultToUpstream not set." msgstr "Ingen incheckning angiven och merge.defaultToUpstream är ej satt." @@ -8323,7 +8354,7 @@ msgstr "" #, c-format msgid "When finished, apply stashed changes with `git stash pop`\n" -msgstr "När färdig, applicerade sparade ändringar med \"git stash pop\"\n" +msgstr "När färdig, applicerade sparade ändringar med â€git stash popâ€\n" #, c-format msgid "warning: tag input does not pass fsck: %s" @@ -8339,11 +8370,11 @@ msgstr "%d (FSCK_IGNORE?) skulle aldrig utlösa detta Ã¥teranrop" #, c-format msgid "could not read tagged object '%s'" -msgstr "kunde inte läsa det taggade objektet \"%s\"" +msgstr "kunde inte läsa det taggade objektet â€%sâ€" #, c-format msgid "object '%s' tagged as '%s', but is a '%s' type" -msgstr "objektet \"%s\" taggat som \"%s\", men är av typen \"%s\"" +msgstr "objektet â€%s†taggat som â€%sâ€, men är av typen â€%sâ€" msgid "could not read from stdin" msgstr "kunde inte läsa frÃ¥n standard in" @@ -8419,7 +8450,7 @@ msgstr "Katalogen %s är i indexet och inte en undermodul?" msgid "Please stage your changes to .gitmodules or stash them to proceed" msgstr "" -"Köa dina ändringar i .gitmodules eller använd \"stash\" för att fortsätta" +"Köa dina ändringar i .gitmodules eller använd â€stash†för att fortsätta" #, c-format msgid "%.*s is in index" @@ -8433,11 +8464,11 @@ msgstr "hoppa över fel vid flytt/namnändring" #, c-format msgid "destination '%s' is not a directory" -msgstr "destinationen \"%s\" är ingen katalog" +msgstr "destinationen â€%s†är ingen katalog" #, c-format msgid "Checking rename of '%s' to '%s'\n" -msgstr "Kontrollerar namnbyte av \"%s\" till \"%s\"\n" +msgstr "Kontrollerar namnbyte av â€%s†till â€%sâ€\n" msgid "bad source" msgstr "felaktig källa" @@ -8448,8 +8479,8 @@ msgstr "destinationen finns" msgid "can not move directory into itself" msgstr "kan inte flytta katalog till sig själv" -msgid "cannot move directory over file" -msgstr "kan inte flytta katalog över fil" +msgid "destination already exists" +msgstr "destinationen finns redan" msgid "source directory is empty" msgstr "källkatalogen är tom" @@ -8462,7 +8493,7 @@ msgstr "i konflikt" #, c-format msgid "overwriting '%s'" -msgstr "skriver över \"%s\"" +msgstr "skriver över â€%sâ€" msgid "Cannot overwrite" msgstr "Kan inte skriva över" @@ -8486,7 +8517,7 @@ msgstr "Byter namn pÃ¥ %s till %s\n" #, c-format msgid "renaming '%s' failed" -msgstr "misslyckades byta namn pÃ¥ \"%s\"" +msgstr "misslyckades byta namn pÃ¥ â€%sâ€" msgid "git name-rev [<options>] <commit>..." msgstr "git name-rev [<flaggor>] <incheckning>..." @@ -8519,7 +8550,7 @@ msgid "annotate text from stdin" msgstr "annotera text frÃ¥n standard in" msgid "allow to print `undefined` names (default)" -msgstr "tillÃ¥t att skriva \"odefinierade\" namn (standard)" +msgstr "tillÃ¥t att skriva â€odefinierade†namn (standard)" msgid "dereference tags in the input (internal use)" msgstr "avreferera taggar i indata (används internt)" @@ -8611,14 +8642,14 @@ msgstr "Skriv/redigera anteckningar för följande objekt:" #, c-format msgid "unable to start 'show' for object '%s'" -msgstr "kunde inte starta \"show\" för objektet \"%s\"" +msgstr "kunde inte starta â€show†för objektet â€%sâ€" msgid "could not read 'show' output" -msgstr "kunde inte läsa utdata frÃ¥n \"show\"" +msgstr "kunde inte läsa utdata frÃ¥n â€showâ€" #, c-format msgid "failed to finish 'show' for object '%s'" -msgstr "kunde inte avsluta \"show\" för objektet \"%s\"" +msgstr "kunde inte avsluta â€show†för objektet â€%sâ€" msgid "please supply the note contents using either -m or -F option" msgstr "ange innehÃ¥ll för anteckningen med antingen -m eller -F" @@ -8632,30 +8663,30 @@ msgstr "anteckningens innehÃ¥ll har lämnats kvar i %s" #, c-format msgid "could not open or read '%s'" -msgstr "kunde inte öppna eller läsa \"%s\"" +msgstr "kunde inte öppna eller läsa â€%sâ€" #, c-format msgid "failed to resolve '%s' as a valid ref." -msgstr "kunde inte slÃ¥ upp \"%s\" som en giltig referens." +msgstr "kunde inte slÃ¥ upp â€%s†som en giltig referens." #, c-format msgid "failed to read object '%s'." -msgstr "kunde inte läsa objektet \"%s\"." +msgstr "kunde inte läsa objektet â€%sâ€." #, c-format msgid "cannot read note data from non-blob object '%s'." -msgstr "kan inte läsa anteckningsdata frÃ¥n icke-blob-objektet \"%s\"." +msgstr "kan inte läsa anteckningsdata frÃ¥n icke-blob-objektet â€%sâ€." #, c-format msgid "failed to copy notes from '%s' to '%s'" -msgstr "misslyckades kopiera anteckningar frÃ¥n \"%s\" till \"%s\"" +msgstr "misslyckades kopiera anteckningar frÃ¥n â€%s†till â€%sâ€" #. TRANSLATORS: the first %s will be replaced by a git #. notes command: 'add', 'merge', 'remove', etc. #. #, c-format msgid "refusing to %s notes in %s (outside of refs/notes/)" -msgstr "vägrar utföra \"%s\" pÃ¥ anteckningar i %s (utanför refs/notes/)" +msgstr "vägrar utföra â€%s†pÃ¥ anteckningar i %s (utanför refs/notes/)" #, c-format msgid "no note found for object %s." @@ -8694,7 +8725,7 @@ msgid "" "existing notes" msgstr "" "Kan inte lägga till anteckningar. Hittade befintliga anteckningar för " -"objektet %s. Använd \"-f\" för att skriva över befintliga anteckningar" +"objektet %s. Använd â€-f†för att skriva över befintliga anteckningar" #, c-format msgid "Overwriting existing notes for object %s\n" @@ -8719,7 +8750,7 @@ msgid "" "existing notes" msgstr "" "Kan inte kopiera anteckningar. Hittade befintliga anteckningar för objektet " -"%s. Använd \"-f\" för att skriva över befintliga anteckningar" +"%s. Använd â€-f†för att skriva över befintliga anteckningar" #, c-format msgid "missing notes on source object %s. Cannot copy." @@ -8730,8 +8761,8 @@ 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 "" -"Flaggorna -m/-F/-c/-C rekommenderas inte för underkommandot \"edit\".\n" -"Använd \"git notes add -f -m/-F/-c/-C\" istället.\n" +"Flaggorna -m/-F/-c/-C rekommenderas inte för underkommandot â€editâ€.\n" +"Använd â€git notes add -f -m/-F/-c/-C†istället.\n" msgid "failed to delete ref NOTES_MERGE_PARTIAL" msgstr "misslyckades ta bort referensen NOTES_MERGE_PARTIAL" @@ -8740,7 +8771,7 @@ msgid "failed to delete ref NOTES_MERGE_REF" msgstr "misslyckades ta bort referensen NOTES_MERGE_REF" msgid "failed to remove 'git notes merge' worktree" -msgstr "misslyckades ta bort arbetskatalogen för \"git notes merge\"" +msgstr "misslyckades ta bort arbetskatalogen för â€git notes mergeâ€" msgid "failed to read ref NOTES_MERGE_PARTIAL" msgstr "misslyckades läsa references NOTES_MERGE_PARTIAL" @@ -8813,12 +8844,12 @@ msgid "" "abort'.\n" msgstr "" "Automatisk sammanslagning av anteckningar misslyckades. Rätta konflikter i " -"%s och checka in resultatet med \"git notes merge --commit\", eller avbryt " -"sammanslagningen med \"git notes merge --abort\".\n" +"%s och checka in resultatet med â€git notes merge --commitâ€, eller avbryt " +"sammanslagningen med â€git notes merge --abortâ€.\n" #, c-format msgid "Failed to resolve '%s' as a valid ref." -msgstr "Kunde inte slÃ¥ upp \"%s\" som en giltig referens." +msgstr "Kunde inte slÃ¥ upp â€%s†som en giltig referens." #, c-format msgid "Object %s has no note\n" @@ -8844,7 +8875,7 @@ msgstr "använd anteckningar frÃ¥n <anteckningsref>" #, c-format msgid "unknown subcommand: `%s'" -msgstr "okänt underkommando: \"%s\"" +msgstr "okänt underkommando: â€%sâ€" msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" msgstr "git pack-objects --stdout [<flaggor>] [< <reflista> | < <objektlista>]" @@ -8895,7 +8926,7 @@ msgstr "misslyckades ta status pÃ¥ %s" #, c-format msgid "failed utime() on %s" -msgstr "\"utime()\" misslyckades pÃ¥ %s" +msgstr "â€utime()†misslyckades pÃ¥ %s" msgid "failed to write bitmap index" msgstr "misslyckade skriva bitkarteindex" @@ -8956,6 +8987,10 @@ msgid "inconsistency with delta count" msgstr "deltaräknaren är inkonsekvent" #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "felaktigt värde för pack.allowPackReuse: â€%sâ€" + +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -8975,7 +9010,7 @@ msgstr "kunde inte hämta typ för objektet %s i paketet %s" #, c-format msgid "could not find pack '%s'" -msgstr "kunde inte hitta paketet \"%s\"" +msgstr "kunde inte hitta paketet â€%sâ€" #, c-format msgid "packfile %s cannot be accessed" @@ -9021,11 +9056,11 @@ msgstr "kan inte tvinga lösa objekt" #, c-format msgid "not a rev '%s'" -msgstr "inte en referens \"%s\"" +msgstr "inte en referens â€%sâ€" #, c-format msgid "bad revision '%s'" -msgstr "felaktig revision \"%s\"" +msgstr "felaktig revision â€%sâ€" msgid "unable to add recent objects" msgstr "kan inte lägga till nya objekt" @@ -9036,7 +9071,7 @@ msgstr "indexversionen %s stöds ej" #, c-format msgid "bad index version '%s'" -msgstr "felaktig indexversion \"%s\"" +msgstr "felaktig indexversion â€%sâ€" msgid "show progress meter during object writing phase" msgstr "visa förloppsindikator under objektskrivningsfasen" @@ -9141,7 +9176,7 @@ msgid "pack compression level" msgstr "komprimeringsgrad för paket" msgid "do not hide commits by grafts" -msgstr "göm inte incheckningar med ympningar (\"grafts\")" +msgstr "göm inte incheckningar med ympningar (â€graftsâ€)" msgid "use a bitmap index if available to speed up counting objects" msgstr "använd bitkartindex om tillgängligt för att räkna objekt snabbare" @@ -9190,9 +9225,6 @@ msgstr "minsta packstorlek är 1 MiB" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin kan inte användas för att bygga ett indexerbart paket" -msgid "cannot use --filter without --stdout" -msgstr "kan inte använda --filter utan --stdout" - msgid "cannot use --filter with --stdin-packs" msgstr "kan inte använda --filter med --stdin-packs" @@ -9205,19 +9237,16 @@ msgstr "kan inte använda intern revisionslista med --cruft" msgid "cannot use --stdin-packs with --cruft" msgstr "kan inte använda --stdin-packs med --cruft" -msgid "cannot use --max-pack-size with --cruft" -msgstr "kan inte använda --max-pack-size med --cruft" - msgid "Enumerating objects" msgstr "Räknar upp objekt" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "Totalt %<PRIu32> (delta %<PRIu32>), Ã¥teranvände %<PRIu32> (delta %<PRIu32>), " -"paket-Ã¥teranvända %<PRIu32>" +"paket-Ã¥teranvända %<PRIu32> (frÃ¥n %<PRIuMAX>)" msgid "" "'git pack-redundant' is nominated for removal.\n" @@ -9226,9 +9255,9 @@ msgid "" "and let us know you still use it by sending an e-mail\n" "to <git@vger.kernel.org>. Thanks.\n" msgstr "" -"\"git pack-redundant\" har nominerats för borttagning.\n" +"â€git pack-redundant†har nominerats för borttagning.\n" "Om du fortfarande använder kommandot, lägg till flaggan\n" -"\"--i-still-use-this\" pÃ¥ kommandoraden och berätta för\n" +"â€--i-still-use-this†pÃ¥ kommandoraden och berätta för\n" "oss att du fortfarande använder det pÃ¥ e-post till\n" "<git@vger.kernel.org>. Tack.\n" @@ -9279,7 +9308,7 @@ msgid "limit traversal to objects outside promisor packfiles" msgstr "begränsa vandring av objekt utanför kontraktspackfiler." msgid "cannot prune in a precious-objects repo" -msgstr "kan inte rensa i ett \"precious-objekt\"-arkiv" +msgstr "kan inte rensa i ett â€precious-objektâ€-arkiv" msgid "git pull [<options>] [<repository> [<refspec>...]]" msgstr "git pull [<flaggor>] [<arkiv> [<refspec>...]]" @@ -9343,7 +9372,7 @@ msgid "" "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 "" -"Du bad om att hämta frÃ¥n fjärren \"%s\", men angav inte nÃ¥gon\n" +"Du bad om att hämta frÃ¥n fjärren â€%sâ€, men angav inte nÃ¥gon\n" "gren. Eftersom det inte är den fjärr som är konfigurerad som\n" "standard för aktuell gren mÃ¥ste du ange en gren pÃ¥ kommandoraden." @@ -9377,7 +9406,7 @@ msgid "" "Your configuration specifies to merge with the ref '%s'\n" "from the remote, but no such ref was fetched." msgstr "" -"Dina inställningar anger sammanslagning med referensen \"%s\"\n" +"Dina inställningar anger sammanslagning med referensen â€%sâ€\n" "frÃ¥n fjärren, men nÃ¥gon sÃ¥dan referens togs inte emot." #, c-format @@ -9404,13 +9433,13 @@ msgid "" msgstr "" "Du har avvikande grenar och mÃ¥ste ange hur de skall förlikas.\n" "Du kan göra detta genom att köra ett av följande kommando innan du\n" -"gör \"pull\" nästa gÃ¥ng: \n" +"gör â€pull†nästa gÃ¥ng: \n" "\n" " git config pull.rebase false # sammanslagning\n" " git config pull.rebase true # ombasering\n" " git config pull.ff only # endast snabbspolning\n" "\n" -"Du kan ersätta \"git config\" med \"git config --global\" för att välja en\n" +"Du kan ersätta â€git config†med â€git config --global†för att välja en\n" "förvald inställning för alla arkiv. Du kan ocksÃ¥ ange --rebase, --no-rebase\n" "eller --ff-only pÃ¥ kommandoraden för att överstyra det konfigurerade\n" "förvalet vid körning.\n" @@ -9422,7 +9451,7 @@ msgid "pull with rebase" msgstr "pull med ombasering" msgid "Please commit or stash them." -msgstr "Checka in eller använd \"stash\" pÃ¥ dem." +msgstr "Checka in eller använd â€stash†pÃ¥ dem." #, c-format msgid "" @@ -9479,8 +9508,8 @@ msgid "" "To choose either option permanently, see push.default in 'git help config'.\n" msgstr "" "\n" -"För att välja ett av alternativen permanent, se push.default i \"git help " -"config\".\n" +"För att välja ett av alternativen permanent, se push.default i â€git help " +"configâ€.\n" msgid "" "\n" @@ -9490,9 +9519,9 @@ msgid "" msgstr "" "\n" "För att undvika att en uppströmsgren automatiskt konfigureras när dess namn\n" -"inte motsvarar den lokala grenen, se värdet \"simple\" i branch." +"inte motsvarar den lokala grenen, se värdet â€simple†i branch." "autoSetupMerge\n" -"i \"git help config\".\n" +"i â€git help configâ€.\n" #, c-format msgid "" @@ -9539,7 +9568,7 @@ msgid "" msgstr "" "\n" "För att detta ska ske automatiskt för grenar som saknar en spÃ¥rande\n" -"uppströmsgren, se \"push.autoSetupRemote\" i \"git help config\".\n" +"uppströmsgren, se â€push.autoSetupRemote†i â€git help configâ€.\n" #, c-format msgid "" @@ -9563,7 +9592,7 @@ msgid "" "You didn't specify any refspecs to push, and push.default is \"nothing\"." msgstr "" "Du angav inga referensspecifikationer att sända, och push.default är " -"\"nothing\"." +"â€nothingâ€." #, c-format msgid "" @@ -9571,8 +9600,8 @@ msgid "" "your current branch '%s', without telling me what to push\n" "to update which remote branch." msgstr "" -"Du sänder till fjärren \"%s\", som inte är uppströms för den\n" -"aktuella grenen \"%s\", utan att tala om för mig vad som\n" +"Du sänder till fjärren â€%sâ€, som inte är uppströms för den\n" +"aktuella grenen â€%sâ€, utan att tala om för mig vad som\n" "ska sändas för att uppdatera fjärrgrenen." msgid "" @@ -9583,8 +9612,8 @@ msgid "" msgstr "" "Uppdateringar avvisades dÃ¥ änden pÃ¥ din befintliga gren är bakom\n" "dess fjärrmotsvarighet. Om du vill integrera fjärrändringarna,\n" -"använd \"git pull\" innan du sänder igen.\t\n" -"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer." +"använd â€git pull†innan du sänder igen.\t\n" +"Se avsnittet â€Note about fast-forward†i â€git push --help†för detaljer." msgid "" "Updates were rejected because a pushed branch tip is behind its remote\n" @@ -9593,10 +9622,9 @@ msgid "" "See the 'Note about fast-forwards' in 'git push --help' for details." msgstr "" "Uppdateringar avvisades dÃ¥ änden pÃ¥ en gren som sänds in är bakom dess\n" -"fjärrmotsvarighet. Om du vill integrera fjärrändringarna, använd \"git pull" -"\"\n" +"fjärrmotsvarighet. Om du vill integrera fjärrändringarna, använd â€git pullâ€\n" "innan du sänder igen.\n" -"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer." +"Se avsnittet â€Note about fast-forward†i â€git push --help†för detaljer." msgid "" "Updates were rejected because the remote contains work that you do not\n" @@ -9607,9 +9635,9 @@ msgid "" msgstr "" "Uppdateringar avvisades dÃ¥ fjärren innehÃ¥ller ändringar som du inte\n" "har lokalt. Det beror oftast pÃ¥ att ett annat arkiv har sänt in samma\n" -"referenser. Om du vill integrera fjärrändringarna, använd \"git pull\"\n" +"referenser. Om du vill integrera fjärrändringarna, använd â€git pullâ€\n" "innan du sänder igen.\n" -"Se avsnittet \"Note about fast-forwards\" i \"git push --help\" för detaljer." +"Se avsnittet â€Note about fast-forwards†i â€git push --help†för detaljer." msgid "Updates were rejected because the tag already exists in the remote." msgstr "Uppdateringarna avvisades eftersom taggen redan finns pÃ¥ fjärren." @@ -9622,7 +9650,7 @@ msgstr "" "Du kan inte uppdatera en fjärr-referens som pekar pÃ¥ ett objekt som\n" "inte är en incheckning, eller uppdatera en fjärr-referens sÃ¥ att den\n" "pekar pÃ¥ nÃ¥got som inte är en incheckning, utan att använda flaggan\n" -"\"--force\".\n" +"â€--forceâ€.\n" msgid "" "Updates were rejected because the tip of the remote-tracking branch has\n" @@ -9632,8 +9660,8 @@ msgid "" msgstr "" "Uppdateringar avvisades dÃ¥ änden pÃ¥ din befintliga gren är bakom\n" "dess fjärrmotsvarighet. Om du vill integrera fjärrändringarna,\n" -"använd \"git pull\" innan du sänder igen.\n" -"Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer." +"använd â€git pull†innan du sänder igen.\n" +"Se avsnittet â€Note about fast-forward†i â€git push --help†för detaljer." #, c-format msgid "Pushing to %s\n" @@ -9641,7 +9669,7 @@ msgstr "Sänder till %s\n" #, c-format msgid "failed to push some refs to '%s'" -msgstr "misslyckades sända vissa referenser till \"%s\"" +msgstr "misslyckades sända vissa referenser till â€%sâ€" msgid "" "recursing into submodule with push.recurseSubmodules=only; using on-demand " @@ -9652,7 +9680,7 @@ msgstr "" #, c-format msgid "invalid value for '%s'" -msgstr "ogiltigt värde för \"%s\"" +msgstr "ogiltigt värde för â€%sâ€" msgid "repository" msgstr "arkiv" @@ -9714,7 +9742,7 @@ msgstr "--delete kan inte användas utan referenser" #, c-format msgid "bad repository '%s'" -msgstr "felaktigt arkiv \"%s\"" +msgstr "felaktigt arkiv â€%sâ€" msgid "" "No configured push destination.\n" @@ -9762,7 +9790,7 @@ msgid "notes" msgstr "anteckningar" msgid "passed to 'git log'" -msgstr "sänds till \"git log\"" +msgstr "sänds till â€git logâ€" msgid "only emit output related to the first range" msgstr "visa endast utdata för det första intervallet" @@ -9772,15 +9800,15 @@ msgstr "visa endast utdata för det andra intervallet" #, c-format msgid "not a revision: '%s'" -msgstr "inte en revision: \"%s\"" +msgstr "inte en revision: â€%sâ€" #, c-format msgid "not a commit range: '%s'" -msgstr "inte ett incheckningsintervall: \"%s\"" +msgstr "inte ett incheckningsintervall: â€%sâ€" #, c-format msgid "not a symmetric range: '%s'" -msgstr "inte ett symmetriskt intervall: \"%s\"" +msgstr "inte ett symmetriskt intervall: â€%sâ€" msgid "need two commit ranges" msgstr "behöver tvÃ¥ incheckningsintervall" @@ -9864,7 +9892,7 @@ msgstr "" #, c-format msgid "could not read '%s'." -msgstr "kunde inte läsa \"%s\"." +msgstr "kunde inte läsa â€%sâ€." #, c-format msgid "could not create temporary %s" @@ -9881,23 +9909,23 @@ msgstr "en basincheckning mÃ¥ste anges med --upstream eller --onto" #, c-format msgid "%s requires the merge backend" -msgstr "%s kräver \"merge\"-bakändan" +msgstr "%s kräver â€mergeâ€-bakändan" #, c-format msgid "invalid onto: '%s'" -msgstr "ogiltig \"onto\": \"%s\"" +msgstr "ogiltig â€ontoâ€: â€%sâ€" #, c-format msgid "invalid orig-head: '%s'" -msgstr "ogiltig \"orig-head\": \"%s\"" +msgstr "ogiltig â€orig-headâ€: â€%sâ€" #, c-format msgid "ignoring invalid allow_rerere_autoupdate: '%s'" -msgstr "ignorera ogiltigt allow_rerere_autoupdate: \"%s\"" +msgstr "ignorera ogiltigt allow_rerere_autoupdate: â€%sâ€" #, c-format msgid "could not remove '%s'" -msgstr "kunde inte ta bort \"%s\"" +msgstr "kunde inte ta bort â€%sâ€" msgid "" "Resolve all conflicts manually, mark them as resolved with\n" @@ -9907,10 +9935,10 @@ msgid "" "abort\"." msgstr "" "Lös alla konflikter manuellt, märk dem som lösta med\n" -"\"git add/rm <filer_i_konflikt>\", kör sedan \"git rebase --continue\".\n" -"Du kan hoppa över incheckningen istället: kör \"git rebase --skip\".\n" -"För att avbryta och Ã¥tergÃ¥ till där du var före ombaseringen, kör \"git " -"rebase --abort\"." +"â€git add/rm <filer_i_konflikt>â€, kör sedan â€git rebase --continueâ€.\n" +"Du kan hoppa över incheckningen istället: kör â€git rebase --skipâ€.\n" +"För att avbryta och Ã¥tergÃ¥ till där du var före ombaseringen, kör â€git " +"rebase --abortâ€." #, c-format msgid "" @@ -9944,10 +9972,9 @@ msgstr "" #, c-format msgid "" -"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"ask" -"\"." -msgstr "" -"okänd tom-typ \"%s\"; giltiga värden är \"drop\", \"keep\" och \"ask\"." +"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and " +"\"ask\"." +msgstr "okänd tom-typ â€%sâ€; giltiga värden är â€dropâ€, â€keep†och â€askâ€." msgid "" "--rebase-merges with an empty string argument is deprecated and will stop " @@ -10011,7 +10038,7 @@ msgid "do not show diffstat of what changed upstream" msgstr "visa inte en diffstat för vad som ändrats uppströms" msgid "add a Signed-off-by trailer to each commit" -msgstr "lägg \"Signed-off-by:\"-släprad till varje incheckning" +msgstr "lägg â€Signed-off-by:â€-släprad till varje incheckning" msgid "make committer date match author date" msgstr "sätt incheckningsdatum till författardatum" @@ -10023,7 +10050,7 @@ msgid "synonym of --reset-author-date" msgstr "synonym för --reset-author-date" msgid "passed to 'git apply'" -msgstr "sänds till \"git apply\"" +msgstr "sänds till â€git applyâ€" msgid "ignore changes in whitespace" msgstr "ignorera ändringar i blanksteg" @@ -10085,7 +10112,7 @@ msgid "try to rebase merges instead of skipping them" msgstr "försök ombasera sammanslagningar istället för att ignorera dem" msgid "use 'merge-base --fork-point' to refine upstream" -msgstr "använd \"merge-base --fork-point\" för att förfina uppström" +msgstr "använd â€merge-base --fork-point†för att förfina uppström" msgid "use the given merge strategy" msgstr "använd angiven sammanslagningsstrategi" @@ -10100,21 +10127,21 @@ msgid "rebase all reachable commits up to the root(s)" msgstr "ombasera alla nÃ¥bara incheckningar upp till roten/rötterna" msgid "automatically re-schedule any `exec` that fails" -msgstr "kör automatiskt alla \"exec\" som misslyckas pÃ¥ nytt" +msgstr "kör automatiskt alla â€exec†som misslyckas pÃ¥ nytt" msgid "apply all changes, even those already present upstream" msgstr "applicera alla ändringar, även de som redan finns uppströms" msgid "It looks like 'git am' is in progress. Cannot rebase." -msgstr "Det verkar som en \"git am\" körs. Kan inte ombasera." +msgstr "Det verkar som en â€git am†körs. Kan inte ombasera." msgid "" "`rebase --preserve-merges` (-p) is no longer supported.\n" "Use `git rebase --abort` to terminate current rebase.\n" "Or downgrade to v2.33, or earlier, to complete the rebase." msgstr "" -"\"rebase --preserve-merges\" (-p) stöds ej längre.\n" -"Använd \"git rebase --abort\" för att avsluta aktuell ombasering.\n" +"â€rebase --preserve-merges†(-p) stöds ej längre.\n" +"Använd â€git rebase --abort†för att avsluta aktuell ombasering.\n" "Eller nedgradera till v2.33 eller tidigare för att slutföra ombaseringen." msgid "" @@ -10123,8 +10150,8 @@ msgid "" "which is no longer supported; use 'merges' instead" msgstr "" "--preserve-merges ersattes av --rebase-merges\n" -"Observera: Din inställning för \"pull.rebase\" kan ocksÃ¥ vara satt till\n" -"\"preserve\", som inte längre stöds; använd \"merges\" istället" +"Observera: Din inställning för â€pull.rebase†kan ocksÃ¥ vara satt till\n" +"â€preserveâ€, som inte längre stöds; använd â€merges†istället" msgid "No rebase in progress?" msgstr "Ingen ombasering pÃ¥gÃ¥r?" @@ -10170,30 +10197,20 @@ msgstr "" "nÃ¥got av värde där.\n" msgid "switch `C' expects a numerical value" -msgstr "flaggan \"C\" förväntar ett numeriskt värde" - -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy kräver --merge eller --interactive" - -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "" -"argument för \"apply\" är inkompatibla med rebase.autoSquash. Överväg att " -"lägga till --no-autosquash" +msgstr "flaggan â€C†förväntar ett numeriskt värde" msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" msgstr "" -"argument för \"apply\" är inkompatibla med rebase.rebaseMerges. Överväg att " +"argument för â€apply†är inkompatibla med rebase.rebaseMerges. Överväg att " "lägga till --no-rebase-merges" msgid "" "apply options are incompatible with rebase.updateRefs. Consider adding --no-" "update-refs" msgstr "" -"argument för \"apply\" är inkompatibla med rebase.updateRefs. Överväg att " +"argument för â€apply†är inkompatibla med rebase.updateRefs. Överväg att " "lägga till --no-update-refs" #, c-format @@ -10205,14 +10222,14 @@ msgstr "--reschedule-failed-exec kräver --exec eller --interactive" #, c-format msgid "invalid upstream '%s'" -msgstr "felaktig uppström \"%s\"" +msgstr "felaktig uppström â€%sâ€" msgid "Could not create new root commit" msgstr "kunde inte skapa ny rotincheckning" #, c-format msgid "no such branch/commit '%s'" -msgstr "ingen sÃ¥dan gren/incheckning: \"%s\"" +msgstr "ingen sÃ¥dan gren/incheckning: â€%sâ€" #, c-format msgid "No such ref: %s" @@ -10223,15 +10240,15 @@ msgstr "Kunde inte bestämma en incheckning för HEAD" #, c-format msgid "'%s': need exactly one merge base with branch" -msgstr "\"%s\": behöver precis en sammanslagningsbas med gren" +msgstr "â€%sâ€: behöver precis en sammanslagningsbas med gren" #, c-format msgid "'%s': need exactly one merge base" -msgstr "\"%s\": behöver precis en sammanslagningsbas" +msgstr "â€%sâ€: behöver precis en sammanslagningsbas" #, c-format msgid "Does not point to a valid commit '%s'" -msgstr "Pekar inte pÃ¥ en giltig incheckning: \"%s\"" +msgstr "Pekar inte pÃ¥ en giltig incheckning: â€%sâ€" msgid "HEAD is up to date." msgstr "HEAD är à jour." @@ -10290,17 +10307,17 @@ msgid "" msgstr "" "Normalt tillÃ¥ts inte uppdatering av aktuell gren i ett icke-naket\n" "arkiv, dÃ¥ index och arbetskatalog inte kommer stämma med det du\n" -"sände och \"git reset --hard\" krävs för att fÃ¥ arbetskatalogen och\n" +"sände och â€git reset --hard†krävs för att fÃ¥ arbetskatalogen och\n" "HEAD att stämma överens.\n" "\n" -"Du kan ställa in variabeln \"receive.denyCurrentBranch\" till\n" -"\"ignore\" eller \"warn\" i fjärrarkivet för att tillÃ¥ta sändning till\n" +"Du kan ställa in variabeln â€receive.denyCurrentBranch†till\n" +"â€ignore†eller â€warn†i fjärrarkivet för att tillÃ¥ta sändning till\n" "dess aktuella gren; detta rekommenderas dock inte sÃ¥vida du inte\n" "sett till att dess arbetskatalog uppdateras till det tu sände in\n" "pÃ¥ annat sätt.\n" "\n" "För att undvika detta meddelande och fortfarande behÃ¥lla det\n" -"normala beteendet, sätt \"receive.denyCurrentBranch\" till \"refuse\"." +"normala beteendet, sätt â€receive.denyCurrentBranch†till â€refuseâ€." msgid "" "By default, deleting the current branch is denied, because the next\n" @@ -10313,14 +10330,14 @@ msgid "" "To squelch this message, you can set it to 'refuse'." msgstr "" "Normalt tillÃ¥ts inte radering av aktuell gren, eftersom nästa\n" -"\"git clone\" inte kommer innebära att nÃ¥gra filer checkas ut,\n" +"â€git clone†inte kommer innebära att nÃ¥gra filer checkas ut,\n" "vilket är förvirrande.\n" "\n" -"Du kan ställa in variabeln \"receive.denyDeleteCurrent\" till\n" -"\"warn\" eller \"ignore\" i fjärrarkivet för att tillÃ¥ta borttagning\n" +"Du kan ställa in variabeln â€receive.denyDeleteCurrent†till\n" +"â€warn†eller â€ignore†i fjärrarkivet för att tillÃ¥ta borttagning\n" "av aktuell gren, med eller utan varningsmeddelande.\n" "\n" -"För att undvika detta meddelande kan du sätta det till \"refuse\"." +"För att undvika detta meddelande kan du sätta det till â€refuseâ€." msgid "quiet" msgstr "tyst" @@ -10354,7 +10371,7 @@ msgstr "git reflog exists <referens>" #, c-format msgid "invalid timestamp '%s' given to '--%s'" -msgstr "ogiltig tidsstämpel \"%s\" given i \"--%s\"" +msgstr "ogiltig tidsstämpel â€%s†given i â€--%sâ€" msgid "do not actually prune any entries" msgstr "rensa faktiskt inte nÃ¥gra poster" @@ -10515,7 +10532,7 @@ msgstr "fjärrarkivet %s finns redan." #, c-format msgid "Could not setup master '%s'" -msgstr "Kunde inte skapa master \"%s\"" +msgstr "Kunde inte skapa master â€%sâ€" #, c-format msgid "more than one %s" @@ -10523,7 +10540,7 @@ msgstr "mer än en %s" #, c-format msgid "unhandled branch.%s.rebase=%s; assuming 'true'" -msgstr "ohanterad branch.%s.rebase=%s; antar \"true\"" +msgstr "ohanterad branch.%s.rebase=%s; antar â€trueâ€" #, c-format msgid "Could not get fetch map for refspec %s" @@ -10537,11 +10554,11 @@ msgstr "(ta bort)" #, c-format msgid "could not set '%s'" -msgstr "kunde inte ställa in \"%s\"" +msgstr "kunde inte ställa in â€%sâ€" #, c-format msgid "could not unset '%s'" -msgstr "kunde inte ta bort inställning för \"%s\"" +msgstr "kunde inte ta bort inställning för â€%sâ€" #, c-format msgid "" @@ -10551,15 +10568,15 @@ msgid "" msgstr "" "Konfigurationen för %s för remote.pushDefault i:\n" "\t%s:%d\n" -"anger nu den icke-existerande fjärren \"%s\"" +"anger nu den icke-existerande fjärren â€%sâ€" #, c-format msgid "No such remote: '%s'" -msgstr "Ingen sÃ¥dan fjärr: \"%s\"" +msgstr "Ingen sÃ¥dan fjärr: â€%sâ€" #, c-format msgid "Could not rename config section '%s' to '%s'" -msgstr "Kunde inte byta namn pÃ¥ konfigurationssektionen \"%s\" till \"%s\"" +msgstr "Kunde inte byta namn pÃ¥ konfigurationssektionen â€%s†till â€%sâ€" #, c-format msgid "" @@ -10576,11 +10593,11 @@ msgstr "Byter namn pÃ¥ fjärreferenser" #, c-format msgid "deleting '%s' failed" -msgstr "misslyckades ta bort \"%s\"" +msgstr "misslyckades ta bort â€%sâ€" #, c-format msgid "creating '%s' failed" -msgstr "misslyckades skapa \"%s\"" +msgstr "misslyckades skapa â€%sâ€" msgid "" "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n" @@ -10597,7 +10614,7 @@ msgstr[1] "" #, c-format msgid "Could not remove config section '%s'" -msgstr "Kunde inte ta bort konfigurationssektionen \"%s\"" +msgstr "Kunde inte ta bort konfigurationssektionen â€%sâ€" #, c-format msgid " new (next fetch will store in remotes/%s)" @@ -10610,7 +10627,7 @@ msgid " skipped" msgstr " överhoppad" msgid " stale (use 'git remote prune' to remove)" -msgstr " förlegad (använd \"git remote prune\" för att ta bort)" +msgstr " förlegad (använd â€git remote prune†för att ta bort)" msgid " ???" msgstr " ???" @@ -10722,17 +10739,17 @@ msgstr " (status inte förfrÃ¥gad)" msgid " Local branch configured for 'git pull':" msgid_plural " Local branches configured for 'git pull':" -msgstr[0] " Lokal gren konfigurerad för \"git pull\":" -msgstr[1] " Lokala grenar konfigurerade för \"git pull\":" +msgstr[0] " Lokal gren konfigurerad för â€git pullâ€:" +msgstr[1] " Lokala grenar konfigurerade för â€git pullâ€:" msgid " Local refs will be mirrored by 'git push'" -msgstr " Lokala referenser speglas av \"git push\"" +msgstr " Lokala referenser speglas av â€git pushâ€" #, c-format msgid " Local ref configured for 'git push'%s:" msgid_plural " Local refs configured for 'git push'%s:" -msgstr[0] " Lokal referens konfigurerad för \"git push\"%s:" -msgstr[1] " Lokala referenser konfigurerade för \"git push\"%s:" +msgstr[0] " Lokal referens konfigurerad för â€git pushâ€%s:" +msgstr[1] " Lokala referenser konfigurerade för â€git pushâ€%s:" msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "sätt refs/remotes/<namn>/HEAD enligt fjärren" @@ -10787,7 +10804,7 @@ msgstr "rensa fjärrar efter hämtning" #, c-format msgid "No such remote '%s'" -msgstr "Ingen sÃ¥dan fjärr \"%s\"" +msgstr "Ingen sÃ¥dan fjärr â€%sâ€" msgid "add branch" msgstr "lägg till gren" @@ -10803,7 +10820,7 @@ msgstr "returnera alla URL:er" #, c-format msgid "no URLs configured for remote '%s'" -msgstr "ingen URL:er angivna för fjärren \"%s\"" +msgstr "ingen URL:er angivna för fjärren â€%sâ€" msgid "manipulate push URLs" msgstr "manipulera URL:ar för sändning" @@ -10875,6 +10892,10 @@ msgstr "kunde inte stänga temporär fil för refs-ögonblicksbild" msgid "could not remove stale bitmap: %s" msgstr "kunde inte ta bort gammal bitkarta: %s" +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "paketprefixet %s börjar inte med objkat %s" + msgid "pack everything in a single pack" msgstr "packa allt i ett enda paket" @@ -10950,27 +10971,30 @@ msgstr "skriv ett flerpaketsindex för de skapade paketen" msgid "pack prefix to store a pack containing pruned objects" msgstr "paketprefix att lagra ett paket som innehÃ¥ller bortrensade objekt" +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "paketprefix att lagra ett paket som innehÃ¥ller utfiltrerade objekt" + msgid "cannot delete packs in a precious-objects repo" -msgstr "kan inte ta bort paket i ett \"precious-objects\"-arkiv" +msgstr "kan inte ta bort paket i ett â€precious-objectsâ€-arkiv" + +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "flaggan â€%s†kan inte användas med â€%sâ€" msgid "Nothing new to pack." msgstr "Inget nytt att packa." #, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "paketprefixet %s börjar inte med objkat %s" - -#, c-format msgid "renaming pack to '%s' failed" -msgstr "misslyckades byta namn pÃ¥ paket till \"%s\"" +msgstr "misslyckades byta namn pÃ¥ paket till â€%sâ€" #, c-format msgid "pack-objects did not write a '%s' file for pack %s-%s" -msgstr "pack-objects skrev inte en \"%s\"-fil för paketet %s-%s" +msgstr "pack-objects skrev inte en â€%sâ€-fil för paketet %s-%s" #, c-format msgid "could not unlink: %s" -msgstr "kunde inte ta bort: \"%s\"" +msgstr "kunde inte ta bort: â€%sâ€" msgid "git replace [-f] <object> <replacement>" msgstr "git replace [-f] <objekt> <ersättning>" @@ -10992,24 +11016,24 @@ msgid "" "invalid replace format '%s'\n" "valid formats are 'short', 'medium' and 'long'" msgstr "" -"ogiltigt ersättningsformat \"%s\"\n" -"giltiga format är \"short\", \"medium\" och \"long\"" +"ogiltigt ersättningsformat â€%sâ€\n" +"giltiga format är â€shortâ€, â€medium†och â€longâ€" #, c-format msgid "replace ref '%s' not found" -msgstr "ersättningsreferensen \"%s\" hittades inte" +msgstr "ersättningsreferensen â€%s†hittades inte" #, c-format msgid "Deleted replace ref '%s'" -msgstr "Tog bort ersättningsreferensen \"%s\"" +msgstr "Tog bort ersättningsreferensen â€%sâ€" #, c-format msgid "'%s' is not a valid ref name" -msgstr "\"%s\" är inte ett giltigt referensnamn" +msgstr "â€%s†är inte ett giltigt referensnamn" #, c-format msgid "replace ref '%s' already exists" -msgstr "ersättningsreferensen \"%s\" finns redan" +msgstr "ersättningsreferensen â€%s†finns redan" #, c-format msgid "" @@ -11018,8 +11042,8 @@ msgid "" "while '%s' points to a replacement object of type '%s'." msgstr "" "Objekt mÃ¥ste vara av samma typ.\n" -"\"%s\" pekar pÃ¥ ett ersatt objekt med typen \"%s\"\n" -"medan \"%s\" pekar pÃ¥ ett ersättningsobjekt av typen \"%s\"." +"â€%s†pekar pÃ¥ ett ersatt objekt med typen â€%sâ€\n" +"medan â€%s†pekar pÃ¥ ett ersättningsobjekt av typen â€%sâ€." #, c-format msgid "unable to open %s for writing" @@ -11046,7 +11070,7 @@ msgstr "mktree returnerade inte ett objektnamn" #, c-format msgid "unable to fstat %s" -msgstr "kan inte utföra \"fstat\" pÃ¥ %s" +msgstr "kan inte utföra â€fstat†pÃ¥ %s" msgid "unable to write object to database" msgstr "kan inte skriva objektet till databasen" @@ -11060,7 +11084,7 @@ msgstr "misslyckades redigera objektfilen" #, c-format msgid "new object is the same as the old one: '%s'" -msgstr "nytt objekt är samma som det gamla: \"%s\"" +msgstr "nytt objekt är samma som det gamla: â€%sâ€" #, c-format msgid "could not parse %s as a commit" @@ -11068,38 +11092,38 @@ msgstr "kunde inte tolka %s som incheckning" #, c-format msgid "bad mergetag in commit '%s'" -msgstr "felaktig sammanslagningstagg i incheckningen \"%s\"" +msgstr "felaktig sammanslagningstagg i incheckningen â€%sâ€" #, c-format msgid "malformed mergetag in commit '%s'" -msgstr "felformad sammanslagningstagg i incheckningen \"%s\"" +msgstr "felformad sammanslagningstagg i incheckningen â€%sâ€" #, c-format msgid "" "original commit '%s' contains mergetag '%s' that is discarded; use --edit " "instead of --graft" msgstr "" -"den ursprungliga incheckningen \"%s\" innehÃ¥ller sammanslagningstaggen \"%s" -"\" som har förkastats; använd --edit istället för --graft" +"den ursprungliga incheckningen â€%s†innehÃ¥ller sammanslagningstaggen â€%s†" +"som har förkastats; använd --edit istället för --graft" #, c-format msgid "the original commit '%s' has a gpg signature" -msgstr "den ursprungliga incheckningen \"%s\" har en gpg-signatur" +msgstr "den ursprungliga incheckningen â€%s†har en gpg-signatur" msgid "the signature will be removed in the replacement commit!" msgstr "signaturen kommer att tas bort i ersättningsincheckningen!" #, c-format msgid "could not write replacement commit for: '%s'" -msgstr "kunde inte skriva ersättningsincheckning för: \"%s\"" +msgstr "kunde inte skriva ersättningsincheckning för: â€%sâ€" #, c-format msgid "graft for '%s' unnecessary" -msgstr "ympning för \"%s\" behövs inte" +msgstr "ympning för â€%s†behövs inte" #, c-format msgid "new commit is the same as the old one: '%s'" -msgstr "ny incheckning är samma som den gamla: \"%s\"" +msgstr "ny incheckning är samma som den gamla: â€%sâ€" #, c-format msgid "" @@ -11160,6 +11184,76 @@ msgstr "--convert-graft-file tar inga argument" msgid "only one pattern can be given with -l" msgstr "endast ett mönster kan anges med -l" +msgid "need some commits to replay" +msgstr "behöver nÃ¥gra incheckningar för omspelning" + +msgid "--onto and --advance are incompatible" +msgstr "--onto och --advance kan inte kombineras" + +msgid "all positive revisions given must be references" +msgstr "alla positiva revisioner som anges mÃ¥ste vara referenser" + +msgid "argument to --advance must be a reference" +msgstr "argumentet till --advance mÃ¥ste vara en referens" + +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "" +"kan inte flytta mÃ¥let framÃ¥t när det finns flera källor eftersom ordningen " +"inte kan fastställas" + +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "" +"kan inte avgöra om den underförstÃ¥dda processen är --advance eller --onto" + +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "" +"kan inte flytta mÃ¥let framÃ¥t när det finns flera källgrenar eftersom " +"ordningen inte kan fastställas" + +msgid "cannot implicitly determine correct base for --onto" +msgstr "kan inte avgöra den underförstÃ¥dda basen för --onto" + +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(EXPERIMENTELLT!) git replay ([--contained] --onto <nybas> | --advance " +"<gren>) <revisions-intervall>..." + +msgid "make replay advance given branch" +msgstr "lÃ¥t omspelningen flytta den givna grenen framÃ¥t" + +msgid "replay onto given commit" +msgstr "spela om ovanpÃ¥ en given incheckning" + +msgid "advance all branches contained in revision-range" +msgstr "flytta alla grenar som finns i revisionsintervallet framÃ¥t" + +msgid "option --onto or --advance is mandatory" +msgstr "flaggan --onto eller --advance mÃ¥ste anges" + +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "" +"nÃ¥gra flaggor för revisionstraversering kommer överstyras eftersom â€%sâ€-" +"biten i â€struct rev_info†kommer att tvingas" + +msgid "error preparing revisions" +msgstr "fel när revisioner skulle förberedas" + +msgid "replaying down to root commit is not supported yet!" +msgstr "kan ännu inte spela om hela vägen ned till rotincheckningen!" + +msgid "replaying merge commits is not supported yet!" +msgstr "kan ännu inte spela om sammanslagningsincheckningar!" + msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" msgstr "" @@ -11169,11 +11263,11 @@ msgid "register clean resolutions in index" msgstr "registrera rena lösningar i indexet" msgid "'git rerere forget' without paths is deprecated" -msgstr "\"git rerere forget\" utan sökvägar är förÃ¥ldrat" +msgstr "â€git rerere forget†utan sökvägar är förÃ¥ldrat" #, c-format msgid "unable to generate diff for '%s'" -msgstr "misslyckades skapa diff för \"%s\"" +msgstr "misslyckades skapa diff för â€%sâ€" msgid "" "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" @@ -11247,15 +11341,15 @@ msgstr "registrera endast att borttagna sökvägar kommer läggas till senare" #, c-format msgid "Failed to resolve '%s' as a valid revision." -msgstr "Kunde inte slÃ¥ upp \"%s\" som en giltig revision." +msgstr "Kunde inte slÃ¥ upp â€%s†som en giltig revision." #, c-format msgid "Failed to resolve '%s' as a valid tree." -msgstr "Kunde inte slÃ¥ upp \"%s\" som ett giltigt träd." +msgstr "Kunde inte slÃ¥ upp â€%s†som ett giltigt träd." msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead." msgstr "" -"--mixed rekommenderas inte med sökvägar; använd \"git reset -- <sökvägar>\"." +"--mixed rekommenderas inte med sökvägar; använd â€git reset -- <sökvägar>â€." #, c-format msgid "Cannot do %s reset with paths." @@ -11274,11 +11368,11 @@ msgid "" "'--no-refresh' to avoid this." msgstr "" "Det tog %.2f sekunder att uppdatera indexet efter Ã¥terställning.\n" -"Du kan använda \"--no-refresh\" för undvika detta." +"Du kan använda â€--no-refresh†för undvika detta." #, c-format msgid "Could not reset index file to revision '%s'." -msgstr "Kunde inte Ã¥terställa indexfilen till versionen \"%s\"." +msgstr "Kunde inte Ã¥terställa indexfilen till versionen â€%sâ€." msgid "Could not write new index file." msgstr "Kunde inte skriva ny indexfil." @@ -11289,21 +11383,20 @@ msgstr "kan inte hämta diskanvändning för %s" #, c-format msgid "invalid value for '%s': '%s', the only allowed format is '%s'" -msgstr "" -"felaktigt värde för \"%s\": \"%s\", det enda tillÃ¥tna formatet är \"%s\"" +msgstr "felaktigt värde för â€%sâ€: â€%sâ€, det enda tillÃ¥tna formatet är â€%sâ€" msgid "rev-list does not support display of notes" msgstr "rev-list stöder inte visning av anteckningar" #, c-format msgid "marked counting and '%s' cannot be used together" -msgstr "markerad räkning och \"%s\" kan inte användas samtidigt." +msgstr "markerad räkning och â€%s†kan inte användas samtidigt." msgid "git rev-parse --parseopt [<options>] -- [<args>...]" msgstr "git rev-parse --parseopt [<options>] -- [<argument>...]" msgid "keep the `--` passed as an arg" -msgstr "behÃ¥ll \"--\" sänt som argument" +msgstr "behÃ¥ll â€--†sänt som argument" msgid "stop parsing after the first non-option argument" msgstr "sluta tolka efter första argument som inte är flagga" @@ -11315,7 +11408,7 @@ msgid "premature end of input" msgstr "för tidigt slut pÃ¥ indata" msgid "no usage string given before the `--' separator" -msgstr "ingen användningssträng angavs före \"--\"-avdelaren" +msgstr "ingen användningssträng angavs före â€--â€-avdelaren" msgid "missing opt-spec before option flags" msgstr "saknar flagg-spec före alternativflaggor" @@ -11334,7 +11427,7 @@ msgstr "" " eller: git rev-parse --sq-quote [<argument>...]\n" " eller: git rev-parse [<flaggor>] [<argument>...]\n" "\n" -"Kör \"git rev-parse --parseopt -h\" för mer information om den första " +"Kör â€git rev-parse --parseopt -h†för mer information om den första " "varianten." msgid "--resolve-git-dir requires an argument" @@ -11342,7 +11435,7 @@ msgstr "--resolve-git-dir kräver ett argument" #, c-format msgid "not a gitdir '%s'" -msgstr "inte en gitkatalog \"%s\"" +msgstr "inte en gitkatalog â€%sâ€" msgid "--git-path requires an argument" msgstr "--git-path kräver ett argument" @@ -11367,18 +11460,12 @@ msgstr "--prefix kräver ett argument" msgid "unknown mode for --abbrev-ref: %s" msgstr "okänt läge för --abbrev-ref: %s" -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden kan endast användas tillsammans med --branches" - -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden kan kan inte användas tillsammans med --tags" - -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden kan kan inte användas tillsammans med --remotes" - msgid "this operation must be run in a work tree" msgstr "funktionen mÃ¥ste köras i en arbetskatalog" +msgid "Could not read the index" +msgstr "Kunde inte läsa indexet" + #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "okänt läge för --show-object-format: %s" @@ -11405,7 +11492,7 @@ msgstr "git cherry-pick (--continue | --skip | --abort | --quit)" #, c-format msgid "option `%s' expects a number greater than zero" -msgstr "flaggan \"%s\" antar ett numeriskt värde större än noll" +msgstr "flaggan â€%s†antar ett numeriskt värde större än noll" #, c-format msgid "%s: %s cannot be used with %s" @@ -11454,13 +11541,13 @@ msgid "keep redundant, empty commits" msgstr "behÃ¥ll redundanta, tomma incheckningar" msgid "use the 'reference' format to refer to commits" -msgstr "använd \"referens\"-format för att referera till incheckningar" +msgstr "använd â€referensâ€-format för att referera till incheckningar" msgid "revert failed" -msgstr "\"revert\" misslyckades" +msgstr "â€revert†misslyckades" msgid "cherry-pick failed" -msgstr "\"cherry-pick\" misslyckades" +msgstr "â€cherry-pick†misslyckades" msgid "" "git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]\n" @@ -11526,11 +11613,11 @@ msgstr "Ingen sökvägsangivelse gavs. Vilka filer ska jag ta bort?" msgid "please stage your changes to .gitmodules or stash them to proceed" msgstr "" -"löa dina ändringar i .gitmodules eller använd \"stash\" för att fortsätta" +"löa dina ändringar i .gitmodules eller använd â€stash†för att fortsätta" #, c-format msgid "not removing '%s' recursively without -r" -msgstr "tar inte bort \"%s\" rekursivt utan -r" +msgstr "tar inte bort â€%s†rekursivt utan -r" #, c-format msgid "git rm: unable to remove %s" @@ -11571,7 +11658,7 @@ msgid "git log --pretty=short | git shortlog [<options>]" msgstr "git log --pretty=short | git shortlog [<flaggor>]" msgid "using multiple --group options with stdin is not supported" -msgstr "mer än en \"--group\"-flagga stöds inte med standard in" +msgstr "mer än en â€--groupâ€-flagga stöds inte med standard in" #, c-format msgid "using %s with stdin is not supported" @@ -11641,7 +11728,7 @@ msgid "show remote-tracking branches" msgstr "visa fjärrspÃ¥rande grenar" msgid "color '*!+-' corresponding to the branch" -msgstr "färga \"*!+-\" enligt grenen" +msgstr "färga â€*!+-†enligt grenen" msgid "show <n> more commits after the common ancestor" msgstr "visa <n> ytterligare incheckningar efter gemensam anfader" @@ -11706,7 +11793,7 @@ msgstr[1] "kan inte hantera mer än %d revisioner." #, c-format msgid "'%s' is not a valid ref." -msgstr "\"%s\" är inte en giltig referens." +msgstr "â€%s†är inte en giltig referens." #, c-format msgid "cannot find commit %s (%s)" @@ -11719,23 +11806,44 @@ msgid "Unknown hash algorithm" msgstr "okänd hashningsalgoritm" msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<mönster>...]" +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" + msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<mönster>]" +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <ref>" + +msgid "reference does not exist" +msgstr "referensen existerar inte" + +msgid "failed to look up reference" +msgstr "misslyckades slÃ¥ upp referensen" + msgid "only show tags (can be combined with heads)" msgstr "visa endast taggar (kan kombineras med huvuden)" msgid "only show heads (can be combined with tags)" msgstr "visa endast huvuden (kan kombineras med taggar)" +msgid "check for reference existence without resolving" +msgstr "kontrollerar att referensen existerar utan att slÃ¥ upp dem" + msgid "stricter reference checking, requires exact ref path" msgstr "striktare referenskontroll, kräver exakt referenssökväg" @@ -11773,15 +11881,15 @@ msgid "" "directory '%s' contains untracked files, but is not in the sparse-checkout " "cone" msgstr "" -"katalogen \"%s\" innehÃ¥ller ospÃ¥rade filer, men är inte i omrÃ¥det som ages i " -"\"sparse-checkout\"" +"katalogen â€%s†innehÃ¥ller ospÃ¥rade filer, men är inte i omrÃ¥det som ages i " +"â€sparse-checkoutâ€" #, c-format msgid "failed to remove directory '%s'" -msgstr "misslyckades ta bort katalogen \"%s\"" +msgstr "misslyckades ta bort katalogen â€%sâ€" msgid "failed to create directory for sparse-checkout file" -msgstr "misslyckades skapa katalog för \"sparse-checkout\"-filen" +msgstr "misslyckades skapa katalog för â€sparse-checkoutâ€-filen" msgid "failed to initialize worktree config" msgstr "misslyckades initiera arbetskataloginställning" @@ -11801,15 +11909,15 @@ msgstr "kunde inte skapa inledande kataloger för %s" #, c-format msgid "failed to open '%s'" -msgstr "misslyckades öppna \"%s\"" +msgstr "misslyckades öppna â€%sâ€" #, c-format msgid "could not normalize path %s" -msgstr "kunde inte normalisera sökvägen \"%s\"" +msgstr "kunde inte normalisera sökvägen â€%sâ€" #, c-format msgid "unable to unquote C-style string '%s'" -msgstr "kan inte ta bort citering av C-sträng \"%s\"" +msgstr "kan inte ta bort citering av C-sträng â€%sâ€" msgid "unable to load existing sparse-checkout patterns" msgstr "kunde inte läsa in existerande mönster för gles utcheckning" @@ -11827,8 +11935,8 @@ msgid "" "specify directories rather than patterns. If your directory starts with a " "'!', pass --skip-checks" msgstr "" -"ange kataloger istället för mönster. Om din katalog börjar med ett \"!\", " -"sänd med --skip-checks" +"ange kataloger istället för mönster. Om din katalog börjar med ett â€!â€, sänd " +"med --skip-checks" msgid "" "specify directories rather than patterns. If your directory really has any " @@ -11842,7 +11950,7 @@ msgid "" "'%s' is not a directory; to treat it as a directory anyway, rerun with --" "skip-checks" msgstr "" -"\"%s\" är inte en katalog: för att ändÃ¥ behandla det som en katalog, kör pÃ¥ " +"â€%s†är inte en katalog: för att ändÃ¥ behandla det som en katalog, kör pÃ¥ " "nytt med --skip-checks" #, c-format @@ -11850,7 +11958,7 @@ 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 "" -"sänd med ett inledande snedstreck före sökvägar som \"%s\" om du vill ha en " +"sänd med ett inledande snedstreck före sökvägar som â€%s†om du vill ha en " "enstaka file (se NON-CONE PROBLEMS i manualen git-sparse-checkout)." msgid "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)" @@ -11899,13 +12007,13 @@ msgid "use patterns in <file> instead of the current ones." msgstr "använd mönster i <fil> istället för de nuvarande." msgid "git stash list [<log-options>]" -msgstr "git stash list [<\"log\"-flaggor>]" +msgstr "git stash list [<â€logâ€-flaggor>]" msgid "" "git stash show [-u | --include-untracked | --only-untracked] [<diff-" "options>] [<stash>]" msgstr "" -"git stash show [-u | --include-untracked | --only-untracked] [<\"diff\"-" +"git stash show [-u | --include-untracked | --only-untracked] [<â€diffâ€-" "flaggor>] [<stash>]" msgid "git stash drop [-q | --quiet] [<stash>]" @@ -11953,21 +12061,21 @@ msgstr "git stash create [<meddelande>]" #, c-format msgid "'%s' is not a stash-like commit" -msgstr "\"%s\" är inte en \"stash\"-liknande incheckning" +msgstr "â€%s†är inte en â€stashâ€-liknande incheckning" #, c-format msgid "Too many revisions specified:%s" msgstr "För mÃ¥nga revisioner angivna:%s" msgid "No stash entries found." -msgstr "Inga \"stash\"-poster hittades." +msgstr "Inga â€stashâ€-poster hittades." #, c-format msgid "%s is not a valid reference" msgstr "%s är inte en giltigt referens" msgid "git stash clear with arguments is unimplemented" -msgstr "\"git stash clear\" med argument har inte implementerats" +msgstr "â€git stash clear†med argument har inte implementerats" #, c-format msgid "" @@ -11976,11 +12084,11 @@ msgid "" " to make room.\n" msgstr "" "VARNING: En ospÃ¥rad fil är i vägen för en spÃ¥rad fil! Byter namn\n" -" %s -> %s\n" +" %s → %s\n" " för att lämna plats.\n" msgid "cannot apply a stash in the middle of a merge" -msgstr "kan inte tillämpa en \"stash\" mitt i en sammanslagning" +msgstr "kan inte tillämpa en â€stash†mitt i en sammanslagning" #, c-format msgid "could not generate diff %s^!." @@ -11997,7 +12105,7 @@ msgid "Merging %s with %s" msgstr "SlÃ¥r ihop %s med %s" msgid "Index was not unstashed." -msgstr "Indexet har inte tagits upp ur \"stash\":en" +msgstr "Indexet har inte tagits upp ur â€stashâ€:en" msgid "could not restore untracked files from stash" msgstr "kunde inte Ã¥terställa ospÃ¥rade filer frÃ¥n stash-post" @@ -12011,11 +12119,11 @@ msgstr "Kastade %s (%s)" #, c-format msgid "%s: Could not drop stash entry" -msgstr "%s: Kunde inte kasta \"stash\"-post" +msgstr "%s: Kunde inte kasta â€stashâ€-post" #, c-format msgid "'%s' is not a stash reference" -msgstr "\"%s\" är inte en \"stash\"-referens" +msgstr "â€%s†är inte en â€stashâ€-referens" msgid "The stash entry is kept in case you need it again." msgstr "Stash-posten behÃ¥lls ifall du behöver den igen." @@ -12030,20 +12138,20 @@ msgid "failed to unpack trees" msgstr "misslyckades packa upp träd" msgid "include untracked files in the stash" -msgstr "ta med ospÃ¥rade filer i \"stash\"" +msgstr "ta med ospÃ¥rade filer i â€stashâ€" msgid "only show untracked files in the stash" -msgstr "visa bara ospÃ¥rade filer i \"stash\"" +msgstr "visa bara ospÃ¥rade filer i â€stashâ€" #, c-format msgid "Cannot update %s with %s" msgstr "Kan inte uppdatera %s med %s" msgid "stash message" -msgstr "\"stash\"-meddelande" +msgstr "â€stashâ€-meddelande" msgid "\"git stash store\" requires one <commit> argument" -msgstr "\"git stash store\" kräver ett <incheckning>-argument" +msgstr "â€git stash store†kräver ett <incheckning>-argument" msgid "No staged changes" msgstr "Inga köade ändringar" @@ -12077,13 +12185,13 @@ msgstr "" "Kan inte använda --staged och --include-untracked eller --all samtidigt" msgid "Did you forget to 'git add'?" -msgstr "Glömde du använda \"git add\"?" +msgstr "Glömde du använda â€git addâ€?" msgid "No local changes to save" msgstr "Inga lokala ändringar att spara" msgid "Cannot initialize stash" -msgstr "Kan inte initiera \"stash\"" +msgstr "Kan inte initiera â€stashâ€" msgid "Cannot save the current status" msgstr "Kan inte spara aktuell status" @@ -12102,13 +12210,13 @@ msgid "stash staged changes only" msgstr "stash:a endast köade ändringar" msgid "stash in patch mode" -msgstr "\"stash\" i \"patch\"-läge" +msgstr "â€stash†i â€patchâ€-läge" msgid "quiet mode" msgstr "tyst läge" msgid "include untracked files in stash" -msgstr "ta med ospÃ¥rade filer i \"stash\"" +msgstr "ta med ospÃ¥rade filer i â€stashâ€" msgid "include ignore files" msgstr "ta med ignorerade filer" @@ -12125,23 +12233,23 @@ msgstr "Förväntade fullt referensnamn, fick %s" #, c-format msgid "could not get a repository handle for submodule '%s'" -msgstr "kunde inte fÃ¥ tag i arkivhandtag för undermodulen \"%s\"" +msgstr "kunde inte fÃ¥ tag i arkivhandtag för undermodulen â€%sâ€" #, c-format msgid "" "could not look up configuration '%s'. Assuming this repository is its own " "authoritative upstream." msgstr "" -"kunde inte slÃ¥ upp konfigurationen \"%s\". Antar att arkivet är sin eget " +"kunde inte slÃ¥ upp konfigurationen â€%sâ€. Antar att arkivet är sin eget " "officiella uppström." #, c-format msgid "No url found for submodule path '%s' in .gitmodules" -msgstr "Hittade ingen url för undermodulsökvägen \"%s\" i .gitmodules" +msgstr "Hittade ingen url för undermodulsökvägen â€%s†i .gitmodules" #, c-format msgid "Entering '%s'\n" -msgstr "GÃ¥r in i \"%s\"\n" +msgstr "GÃ¥r in i â€%sâ€\n" #, c-format msgid "" @@ -12172,19 +12280,19 @@ msgstr "git submodule foreach [--quiet] [--recursive] [--] <kommando>" #, c-format msgid "Failed to register url for submodule path '%s'" -msgstr "Misslyckades registrera url för undermodulsökväg \"%s\"" +msgstr "Misslyckades registrera url för undermodulsökväg â€%sâ€" #, c-format msgid "Submodule '%s' (%s) registered for path '%s'\n" -msgstr "Undermodulen \"%s\" (%s) registrerad för sökvägen \"%s\"\n" +msgstr "Undermodulen â€%s†(%s) registrerad för sökvägen â€%sâ€\n" #, c-format msgid "warning: command update mode suggested for submodule '%s'\n" -msgstr "varning: kommandouppdateringsläge föreslogs för undermodulen \"%s\"\n" +msgstr "varning: kommandouppdateringsläge föreslogs för undermodulen â€%sâ€\n" #, c-format msgid "Failed to register update mode for submodule path '%s'" -msgstr "Misslyckades registrera uppdateringsläge för undermodulsökväg \"%s\"" +msgstr "Misslyckades registrera uppdateringsläge för undermodulsökväg â€%sâ€" msgid "suppress output for initializing a submodule" msgstr "dölj utdata frÃ¥n initiering av undermodul" @@ -12194,15 +12302,15 @@ msgstr "git submodule init [<flaggor>] [<sökväg>]" #, c-format msgid "no submodule mapping found in .gitmodules for path '%s'" -msgstr "hittade ingen undermodulmappning i .gitmodules för sökvägen \"%s\"" +msgstr "hittade ingen undermodulmappning i .gitmodules för sökvägen â€%sâ€" #, c-format msgid "could not resolve HEAD ref inside the submodule '%s'" -msgstr "kunde inte bestämma HEAD:s incheckning i undermodulen \"%s\"" +msgstr "kunde inte bestämma HEAD:s incheckning i undermodulen â€%sâ€" #, c-format msgid "failed to recurse into submodule '%s'" -msgstr "misslyckades rekursera in i undermodulen \"%s\"" +msgstr "misslyckades rekursera in i undermodulen â€%sâ€" msgid "suppress submodule status output" msgstr "hindra statusutskrift för undermodul" @@ -12219,11 +12327,11 @@ msgstr "git submodule status [--quitet] [--cached] [--recursive] [<sökväg>...] #, c-format msgid "* %s %s(blob)->%s(submodule)" -msgstr "* %s %s(blob)->%s(submodule)" +msgstr "* %s %s(blob)→%s(submodule)" #, c-format msgid "* %s %s(submodule)->%s(blob)" -msgstr "* %s %s(submodule)->%s(blob)" +msgstr "* %s %s(submodule)→%s(blob)" #, c-format msgid "%s" @@ -12231,7 +12339,7 @@ msgstr "%s" #, c-format msgid "couldn't hash object from '%s'" -msgstr "kunde inte hasha objekt frÃ¥n \"%s\"" +msgstr "kunde inte hasha objekt frÃ¥n â€%sâ€" #, c-format msgid "unexpected mode %o\n" @@ -12245,7 +12353,7 @@ msgstr "jämför incheckningen i indexet med den i undermodulens HEAD" msgid "skip submodules with 'ignore_config' value set to 'all'" msgstr "" -"hoppa över undermoduler där värdet för \"ignore_config\" är satt till \"all\"" +"hoppa över undermoduler där värdet för â€ignore_config†är satt till â€allâ€" msgid "limit the summary size" msgstr "begränsa översiktsstorleken" @@ -12258,15 +12366,15 @@ msgstr "kunde inte hämta en version för HEAD" #, c-format msgid "Synchronizing submodule url for '%s'\n" -msgstr "Synkroniserar undermodul-url för \"%s\"\n" +msgstr "Synkroniserar undermodul-url för â€%sâ€\n" #, c-format msgid "failed to register url for submodule path '%s'" -msgstr "misslyckades registrera url för undermodulsökväg \"%s\"" +msgstr "misslyckades registrera url för undermodulsökväg â€%sâ€" #, c-format msgid "failed to update remote for submodule '%s'" -msgstr "misslyckades uppdatera fjärr för undermodulsökväg \"%s\"" +msgstr "misslyckades uppdatera fjärr för undermodulsökväg â€%sâ€" msgid "suppress output of synchronizing submodule url" msgstr "dölj utdata frÃ¥n synkronisering av undermodul-url" @@ -12279,7 +12387,7 @@ msgid "" "Submodule work tree '%s' contains a .git directory. This will be replaced " "with a .git file by using absorbgitdirs." msgstr "" -"Undermodulsarbetskatalogen \"%s\" innehÃ¥ller en .git-katalog. Denna kommer " +"Undermodulsarbetskatalogen â€%s†innehÃ¥ller en .git-katalog. Denna kommer " "ersättas med en .git-fil med absorbgitdirs." #, c-format @@ -12287,16 +12395,15 @@ msgid "" "Submodule work tree '%s' contains local modifications; use '-f' to discard " "them" msgstr "" -"Undermodulens arbetskatalog \"%s\" har lokala ändringar; \"-f\" kastar bort " -"dem" +"Undermodulens arbetskatalog â€%s†har lokala ändringar; â€-f†kastar bort dem" #, c-format msgid "Cleared directory '%s'\n" -msgstr "Rensade katalogen \"%s\"\n" +msgstr "Rensade katalogen â€%sâ€\n" #, c-format msgid "Could not remove submodule work tree '%s'\n" -msgstr "Kunde inte ta bort undermodulens arbetskatalog \"%s\"\n" +msgstr "Kunde inte ta bort undermodulens arbetskatalog â€%sâ€\n" #, c-format msgid "could not create empty submodule directory %s" @@ -12304,7 +12411,7 @@ msgstr "kunde inte skapa tom undermodulskatalog %s" #, c-format msgid "Submodule '%s' (%s) unregistered for path '%s'\n" -msgstr "Undermodulen \"%s\" (%s) registrerad för sökvägen \"%s\"\n" +msgstr "Undermodulen â€%s†(%s) registrerad för sökvägen â€%sâ€\n" msgid "remove submodule working trees even if they contain local changes" msgstr "" @@ -12319,7 +12426,7 @@ msgstr "" "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<sökväg>...]]" msgid "Use '--all' if you really want to deinitialize all submodules" -msgstr "Använd \"--all\" om du verkligen vill avinitiera alla undermoduler" +msgstr "Använd â€--all†om du verkligen vill avinitiera alla undermoduler" msgid "" "An alternate computed from a superproject's alternate is invalid.\n" @@ -12329,40 +12436,40 @@ msgid "" msgstr "" "En suppleant beräknad frÃ¥n huvudprojektets suppleant är ogiltig.\n" "För att i sÃ¥ fall lÃ¥ta Git klona utan ett suppleant, sätt\n" -"submodule.alternateErrorStrategy till \"info\" eller, likvärdigt, klona\n" -"med \"--reference-if-able\" istället för \"--reference\"." +"submodule.alternateErrorStrategy till â€info†eller, likvärdigt, klona\n" +"med â€--reference-if-able†istället för â€--referenceâ€." #, c-format msgid "could not get a repository handle for gitdir '%s'" -msgstr "kunde inte fÃ¥ tag i arkivhandtag för gitkatalogen \"%s\"" +msgstr "kunde inte fÃ¥ tag i arkivhandtag för gitkatalogen â€%sâ€" #, c-format msgid "submodule '%s' cannot add alternate: %s" -msgstr "undermodulen \"%s\" kan inte lägga till suppleant: %s" +msgstr "undermodulen â€%s†kan inte lägga till suppleant: %s" #, c-format msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized" -msgstr "Värdet \"%s\" i submodule.alternateErrorStrategy förstÃ¥s inte" +msgstr "Värdet â€%s†i submodule.alternateErrorStrategy förstÃ¥s inte" #, c-format msgid "Value '%s' for submodule.alternateLocation is not recognized" -msgstr "Värdet \"%s\" i submodule.alternateLocation förstÃ¥s inte" +msgstr "Värdet â€%s†i submodule.alternateLocation förstÃ¥s inte" #, c-format msgid "refusing to create/use '%s' in another submodule's git dir" -msgstr "vägrar skapa/använda \"%s\" i en annan undermoduls gitkatalog" +msgstr "vägrar skapa/använda â€%s†i en annan undermoduls gitkatalog" #, c-format msgid "clone of '%s' into submodule path '%s' failed" -msgstr "misslyckades klona \"%s\" till undermodulsökvägen \"%s\"" +msgstr "misslyckades klona â€%s†till undermodulsökvägen â€%sâ€" #, c-format msgid "directory not empty: '%s'" -msgstr "katalogen inte tom: \"%s\"" +msgstr "katalogen inte tom: â€%sâ€" #, c-format msgid "could not get submodule directory for '%s'" -msgstr "kunde inte fÃ¥ tag i undermodulkatalog för \"%s\"" +msgstr "kunde inte fÃ¥ tag i undermodulkatalog för â€%sâ€" msgid "alternative anchor for relative paths" msgstr "alternativa ankare för relativa sökvägar" @@ -12396,15 +12503,14 @@ msgstr "" #, c-format msgid "Invalid update mode '%s' configured for submodule path '%s'" -msgstr "" -"Ogiltigt uppdateringsläge \"%s\" konfigurerat för undermodulsökväg \"%s\"" +msgstr "Ogiltigt uppdateringsläge â€%s†konfigurerat för undermodulsökväg â€%sâ€" #, c-format msgid "Submodule path '%s' not initialized" -msgstr "Undermodulsökvägen \"%s\" har inte initierats" +msgstr "Undermodulsökvägen â€%s†har inte initierats" msgid "Maybe you want to use 'update --init'?" -msgstr "Kanske menade du att använda \"update --init\"?" +msgstr "Kanske menade du att använda â€update --initâ€?" #, c-format msgid "Skipping unmerged submodule %s" @@ -12412,67 +12518,67 @@ msgstr "Hoppar över ej sammanslagen undermodul %s" #, c-format msgid "Skipping submodule '%s'" -msgstr "Hoppar över undermodulen \"%s\"" +msgstr "Hoppar över undermodulen â€%sâ€" #, c-format msgid "cannot clone submodule '%s' without a URL" -msgstr "kan inte klona undermodulen \"%s\" utan en URL" +msgstr "kan inte klona undermodulen â€%s†utan en URL" #, c-format msgid "Failed to clone '%s'. Retry scheduled" -msgstr "Misslyckades klona \"%s\". Nytt försök planlagt" +msgstr "Misslyckades klona â€%sâ€. Nytt försök planlagt" #, c-format msgid "Failed to clone '%s' a second time, aborting" -msgstr "Misslyckades klona \"%s\" för andra gÃ¥ngen, avbryter" +msgstr "Misslyckades klona â€%s†för andra gÃ¥ngen, avbryter" #, c-format msgid "Unable to checkout '%s' in submodule path '%s'" -msgstr "Kan inte checka ut \"%s\" i undermodulsökvägen \"%s\"" +msgstr "Kan inte checka ut â€%s†i undermodulsökvägen â€%sâ€" #, c-format msgid "Unable to rebase '%s' in submodule path '%s'" -msgstr "Kan inte ombasera \"%s\" i undermodulsökvägen \"%s\"" +msgstr "Kan inte ombasera â€%s†i undermodulsökvägen â€%sâ€" #, c-format msgid "Unable to merge '%s' in submodule path '%s'" -msgstr "Kan inte slÃ¥ ihop \"%s\" i undermodulsökvägen \"%s\"" +msgstr "Kan inte slÃ¥ ihop â€%s†i undermodulsökvägen â€%sâ€" #, c-format msgid "Execution of '%s %s' failed in submodule path '%s'" -msgstr "Misslyckades köra \"%s %s\" i undermodulsökvägen \"%s\"" +msgstr "Misslyckades köra â€%s %s†i undermodulsökvägen â€%sâ€" #, c-format msgid "Submodule path '%s': checked out '%s'\n" -msgstr "Undermodulsökvägen \"%s\": checkade ut \"%s\"\n" +msgstr "Undermodulsökvägen â€%sâ€: checkade ut â€%sâ€\n" #, c-format msgid "Submodule path '%s': rebased into '%s'\n" -msgstr "Undermodulsökvägen \"%s\": ombaserade in i \"%s\"\n" +msgstr "Undermodulsökvägen â€%sâ€: ombaserade in i â€%sâ€\n" #, c-format msgid "Submodule path '%s': merged in '%s'\n" -msgstr "Undermodulsökvägen \"%s\": sammanslagen i \"%s\"\n" +msgstr "Undermodulsökvägen â€%sâ€: sammanslagen i â€%sâ€\n" #, c-format msgid "Submodule path '%s': '%s %s'\n" -msgstr "Undermodulsökvägen \"%s\": \"%s %s\"\n" +msgstr "Undermodulsökvägen â€%sâ€: â€%s %sâ€\n" #, c-format msgid "Unable to fetch in submodule path '%s'; trying to directly fetch %s:" -msgstr "Kan inte hämta i undermodulsökväg \"%s\"; försökte hämta %s direkt:" +msgstr "Kan inte hämta i undermodulsökväg â€%sâ€; försökte hämta %s direkt:" #, c-format msgid "" "Fetched in submodule path '%s', but it did not contain %s. Direct fetching " "of that commit failed." msgstr "" -"Hämtade i undermodulssökvägen \"%s\", men den innehöll inte %s. Direkt " +"Hämtade i undermodulssökvägen â€%sâ€, men den innehöll inte %s. Direkt " "hämtning av incheckningen misslyckades." #, c-format msgid "could not initialize submodule at path '%s'" -msgstr "kunde inte initiera undermodul i sökvägen \"%s\"" +msgstr "kunde inte initiera undermodul i sökvägen â€%sâ€" #, c-format msgid "" @@ -12484,19 +12590,19 @@ msgstr "" #, c-format msgid "Unable to find current revision in submodule path '%s'" -msgstr "Kan inte hitta aktuell revision i undermodulsökvägen \"%s\"" +msgstr "Kan inte hitta aktuell revision i undermodulsökvägen â€%sâ€" #, c-format msgid "Unable to fetch in submodule path '%s'" -msgstr "Kan inte hämta i undermodulsökväg \"%s\"" +msgstr "Kan inte hämta i undermodulsökväg â€%sâ€" #, c-format msgid "Unable to find %s revision in submodule path '%s'" -msgstr "Kan inte hitta %s revision i undermodulsökvägen \"%s\"" +msgstr "Kan inte hitta %s revision i undermodulsökvägen â€%sâ€" #, c-format msgid "Failed to recurse into submodule path '%s'" -msgstr "Misslyckades rekursera in i undermodulsökväg \"%s\"" +msgstr "Misslyckades rekursera in i undermodulsökväg â€%sâ€" msgid "force checkout updates" msgstr "tvinga utcheckningsuppdateringar" @@ -12514,13 +12620,13 @@ msgid "don't fetch new objects from the remote site" msgstr "hämta inte nya objekt frÃ¥n fjärrplatsen" msgid "use the 'checkout' update strategy (default)" -msgstr "använd uppdateringsstrategin \"checkout\" (utcheckning; förval)" +msgstr "använd uppdateringsstrategin â€checkout†(utcheckning; förval)" msgid "use the 'merge' update strategy" -msgstr "använd uppdateringsstrategin \"merge\" (sammanslagning)" +msgstr "använd uppdateringsstrategin â€merge†(sammanslagning)" msgid "use the 'rebase' update strategy" -msgstr "använd uppdateringsstrategin \"rebase\" (ombasering)" +msgstr "använd uppdateringsstrategin â€rebase†(ombasering)" msgid "create a shallow clone truncated to the specified number of revisions" msgstr "skapa en grund klon trunkerad till angivet antal revisioner" @@ -12548,6 +12654,9 @@ msgstr "" "[no-]recommend-shallow] [--reference <arkiv>] [--recursive] [--[no-]single-" "branch] [--] [<sökväg>...]" +msgid "Failed to resolve HEAD as a valid ref." +msgstr "Misslyckades slÃ¥ upp HEAD som giltig referens." + msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<flaggor>] [<sökväg>...]" @@ -12590,19 +12699,19 @@ msgstr "" #, c-format msgid "creating branch '%s'" -msgstr "skapar grenen \"%s\"" +msgstr "skapar grenen â€%sâ€" #, c-format msgid "Adding existing repo at '%s' to the index\n" -msgstr "Lägger till befintligt arkiv i \"%s\" i indexet\n" +msgstr "Lägger till befintligt arkiv i â€%s†i indexet\n" #, c-format msgid "'%s' already exists and is not a valid git repo" -msgstr "\"%s\" finns redan och är inte ett giltigt git-arkiv" +msgstr "â€%s†finns redan och är inte ett giltigt git-arkiv" #, c-format msgid "A git directory for '%s' is found locally with remote(s):\n" -msgstr "En git-katalog för \"%s\" hittades lokalt med fjärr(ar):\n" +msgstr "En git-katalog för â€%s†hittades lokalt med fjärr(ar):\n" #, c-format msgid "" @@ -12616,41 +12725,41 @@ msgstr "" "Om du vill Ã¥teranvända den lokala git-katalogen istället för att klona pÃ¥ " "nytt frÃ¥n\n" " %s\n" -"kan du använda flaggan \"--force\". Om den lokala git-katalogen inte är " +"kan du använda flaggan â€--forceâ€. Om den lokala git-katalogen inte är " "korrekt\n" "arkiv eller om du är osäker pÃ¥ vad det här betyder, välj ett annat namn med\n" -"flaggan \"--name\"." +"flaggan â€--nameâ€." #, c-format msgid "Reactivating local git directory for submodule '%s'\n" -msgstr "Aktiverar lokal git-katalog för undermodulen \"%s\" pÃ¥ nytt.\n" +msgstr "Aktiverar lokal git-katalog för undermodulen â€%s†pÃ¥ nytt.\n" #, c-format msgid "unable to checkout submodule '%s'" -msgstr "Kan inte checka ut undermodulen \"%s\"" +msgstr "Kan inte checka ut undermodulen â€%sâ€" msgid "please make sure that the .gitmodules file is in the working tree" msgstr "se till att .gitmodules finns i arbetskatalogen" #, c-format msgid "Failed to add submodule '%s'" -msgstr "Misslyckades lägga till undermodulen \"%s\"" +msgstr "Misslyckades lägga till undermodulen â€%sâ€" #, c-format msgid "Failed to register submodule '%s'" -msgstr "Misslyckades registrera undermodulen \"%s\"" +msgstr "Misslyckades registrera undermodulen â€%sâ€" #, c-format msgid "'%s' already exists in the index" -msgstr "\"%s\" finns redan i indexet" +msgstr "â€%s†finns redan i indexet" #, c-format msgid "'%s' already exists in the index and is not a submodule" -msgstr "\"%s\" finns redan i indexet och är inte en undermodul" +msgstr "â€%s†finns redan i indexet och är inte en undermodul" #, c-format msgid "'%s' does not have a commit checked out" -msgstr "\"%s\" har inte nÃ¥gon utcheckad incheckning" +msgstr "â€%s†har inte nÃ¥gon utcheckad incheckning" msgid "branch of repository to add as submodule" msgstr "gren frÃ¥n arkivet att lägga till som undermodul" @@ -12676,11 +12785,11 @@ msgstr "Relativ sökväg kan endast användas frÃ¥n arbetskatalogens toppnivÃ¥" #, c-format msgid "repo URL: '%s' must be absolute or begin with ./|../" -msgstr "arkiv-URL: \"%s\" mÃ¥ste vara absolut eller börja med ./|../" +msgstr "arkiv-URL: â€%s†mÃ¥ste vara absolut eller börja med ./|../" #, c-format msgid "'%s' is not a valid submodule name" -msgstr "\"%s\" är inte ett giltigt namn pÃ¥ undermodul" +msgstr "â€%s†är inte ett giltigt namn pÃ¥ undermodul" msgid "git submodule--helper <command>" msgstr "git submodule--helper <kommando>" @@ -12740,11 +12849,11 @@ msgstr "git tag -v [--format=<format>] <taggnamn>..." #, c-format msgid "tag '%s' not found." -msgstr "taggen \"%s\" hittades inte." +msgstr "taggen â€%s†hittades inte." #, c-format msgid "Deleted tag '%s' (was %s)\n" -msgstr "Tog bort tagg \"%s\" (var %s)\n" +msgstr "Tog bort tagg â€%s†(var %s)\n" #, c-format msgid "" @@ -12756,7 +12865,7 @@ msgstr "" "\n" "Skriv ett meddelande för taggen:\n" " %s\n" -"Rader som inleds med \"%c\" ignoreras.\n" +"Rader som inleds med â€%c†ignoreras.\n" #, c-format msgid "" @@ -12769,7 +12878,7 @@ msgstr "" "\n" "Skriv ett meddelande för taggen:\n" " %s\n" -"Rader som inleds med \"%c\" kommer behÃ¥llas; du kan själv ta bort dem om\n" +"Rader som inleds med â€%c†kommer behÃ¥llas; du kan själv ta bort dem om\n" "du vill.\n" msgid "unable to sign the tag" @@ -12856,15 +12965,15 @@ msgstr "visa endast taggar för objektet" #, c-format msgid "the '%s' option is only allowed in list mode" -msgstr "flaggan \"%s\" är endast tillÃ¥ten i listläge" +msgstr "flaggan â€%s†är endast tillÃ¥ten i listläge" #, c-format msgid "'%s' is not a valid tag name." -msgstr "\"%s\" är inte ett giltigt taggnamn." +msgstr "â€%s†är inte ett giltigt taggnamn." #, c-format msgid "tag '%s' already exists" -msgstr "taggen \"%s\" finns redan" +msgstr "taggen â€%s†finns redan" #, c-format msgid "Invalid cleanup mode %s" @@ -12872,7 +12981,7 @@ msgstr "Felaktigt städningsläge %s" #, c-format msgid "Updated tag '%s' (was %s)\n" -msgstr "Uppdaterad tagg \"%s\" (var %s)\n" +msgstr "Uppdaterad tagg â€%s†(var %s)\n" msgid "pack exceeds maximum allowed size" msgstr "paket är större än tillÃ¥ten maximal storlek" @@ -12904,7 +13013,7 @@ msgstr "misslyckades ta bort katalogen %s" #, c-format msgid "Testing mtime in '%s' " -msgstr "Testar mtime i \"%s\" " +msgstr "Testar mtime i â€%s†" msgid "directory stat info does not change after adding a new file" msgstr "stat-informationen för en katalog ändras inte när nya filer läggs till" @@ -12964,19 +13073,19 @@ msgid "add the specified entry to the index" msgstr "lägg till angiven post i indexet" msgid "mark files as \"not changing\"" -msgstr "markera filer som \"ändras inte\"" +msgstr "markera filer som â€Ã¤ndras inteâ€" msgid "clear assumed-unchanged bit" -msgstr "rensa \"assume-unchanged\"-biten" +msgstr "rensa â€assume-unchangedâ€-biten" msgid "mark files as \"index-only\"" -msgstr "markera filer som \"endast index\"" +msgstr "markera filer som â€endast indexâ€" msgid "clear skip-worktree bit" -msgstr "töm \"skip-worktree\"-biten" +msgstr "töm â€skip-worktreeâ€-biten" msgid "do not touch index-only entries" -msgstr "rör inte \"endast index\"-poster" +msgstr "rör inte â€endast indexâ€-poster" msgid "add to index only; do not add content to object database" msgstr "lägg endast till indexet; lägg inte till innehÃ¥llet i objektdatabasen" @@ -13011,6 +13120,9 @@ msgstr "(för porslin) glöm sparade olösta konflikter" msgid "write index in this format" msgstr "skriv index i detta format" +msgid "report on-disk index format version" +msgstr "rapportera formatversion för indexfilen pÃ¥ disk" + msgid "enable or disable split index" msgstr "aktivera eller inaktivera delat index" @@ -13030,10 +13142,18 @@ msgid "enable or disable file system monitor" msgstr "aktivera eller inaktivera filsystemsövervakning" msgid "mark files as fsmonitor valid" -msgstr "markera filer som \"fsmonitor valid\"" +msgstr "markera filer som â€fsmonitor validâ€" msgid "clear fsmonitor valid bit" -msgstr "töm \"fsmonitor valid\"-bit" +msgstr "töm â€fsmonitor validâ€-bit" + +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "index-version: vad %d, sattes till %d" msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " @@ -13068,7 +13188,7 @@ msgstr "" #, c-format msgid "Untracked cache enabled for '%s'" -msgstr "OspÃ¥rad cache är aktiverad för \"%s\"" +msgstr "OspÃ¥rad cache är aktiverad för â€%sâ€" msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor" msgstr "core.fsmonitor inte satt; sätt om du verkligen vill aktivera fsmonitor" @@ -13182,17 +13302,17 @@ msgid "git worktree unlock <worktree>" msgstr "git worktree unlock <arbetskatalog>" msgid "No possible source branch, inferring '--orphan'" -msgstr "Ingen möjlig källgren, använder \"--orphan\"" +msgstr "Ingen möjlig källgren, använder â€--orphanâ€" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan -b %s %s\n" msgstr "" -"Om meningen var att skapa en arbetskatalog frÃ¥n en ny föräldrals\n" +"Om meningen var att skapa en arbetskatalog frÃ¥n en ny ofödd\n" "gren (gren utan incheckningar) för det här arkivet kan du göra\n" "det med flaggan --orphan:\n" "\n" @@ -13200,13 +13320,13 @@ msgstr "" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan %s\n" msgstr "" -"Om meningen var att skapa en arbetskatalog frÃ¥n en ny föräldrals\n" +"Om meningen var att skapa en arbetskatalog frÃ¥n en ny ofödd\n" "gren (gren utan incheckningar) för det här arkivet kan du göra\n" "det med flaggan --orphan:\n" "\n" @@ -13224,63 +13344,65 @@ msgstr "lÃ¥t tid gÃ¥ ut för arbetskataloger äldre än <tid>" #, c-format msgid "'%s' already exists" -msgstr "\"%s\" finns redan" +msgstr "â€%s†finns redan" #, c-format msgid "unusable worktree destination '%s'" -msgstr "oanvändbar mÃ¥l för arbetskatalog \"%s\"" +msgstr "oanvändbar mÃ¥l för arbetskatalog â€%sâ€" #, 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 "" -"\"%s\" är en saknad men lÃ¥st arbetskatalog;\n" -"använd \"%s -f -f\" för att överstyra, eller \"unlock\" och \"prune\" eller " -"\"remove\" för att rensa" +"â€%s†är en saknad men lÃ¥st arbetskatalog;\n" +"använd â€%s -f -f†för att överstyra, eller â€unlock†och â€prune†eller " +"â€remove†för att rensa" #, c-format msgid "" "'%s' is a missing but already registered worktree;\n" "use '%s -f' to override, or 'prune' or 'remove' to clear" msgstr "" -"\"%s\" är en saknad men redan registrerad arbetskatalog;\n" -"använd \"%s -f\" för att överstyra, eller \"prune\" eller \"remove\" för att " -"rensa" +"â€%s†är en saknad men redan registrerad arbetskatalog;\n" +"använd â€%s -f†för att överstyra, eller â€prune†eller â€remove†för att rensa" #, c-format msgid "failed to copy '%s' to '%s'; sparse-checkout may not work correctly" msgstr "" -"misslyckades kopiera \"%s\" till \"%s\"; sparse-checkout kanske inte kommer " -"att fungera korrekt" +"misslyckades kopiera â€%s†till â€%sâ€; sparse-checkout kanske inte kommer att " +"fungera korrekt" #, c-format msgid "failed to copy worktree config from '%s' to '%s'" -msgstr "" -"misslyckades kopiera arbetskatalogkonfiguration frÃ¥n \"%s\" till \"%s\"" +msgstr "misslyckades kopiera arbetskatalogkonfiguration frÃ¥n â€%s†till â€%sâ€" #, c-format msgid "failed to unset '%s' in '%s'" -msgstr "misslyckades slÃ¥ av \"%s\" i \"%s\"" +msgstr "misslyckades slÃ¥ av â€%s†i â€%sâ€" #, c-format msgid "could not create directory of '%s'" -msgstr "kunde inte skapa katalogen \"%s\"" +msgstr "kunde inte skapa katalogen â€%sâ€" msgid "initializing" msgstr "initierar" #, c-format +msgid "could not find created worktree '%s'" +msgstr "kunde inte hitta den skapade arbetskatalogen â€%sâ€" + +#, c-format msgid "Preparing worktree (new branch '%s')" -msgstr "Förbereder arbetskatalog (ny gren \"%s\")" +msgstr "Förbereder arbetskatalog (ny gren â€%sâ€)" #, c-format msgid "Preparing worktree (resetting branch '%s'; was at %s)" -msgstr "Förbereder arbetskatalog (Ã¥terställer gren \"%s\"; var pÃ¥ %s)" +msgstr "Förbereder arbetskatalog (Ã¥terställer gren â€%sâ€; var pÃ¥ %s)" #, c-format msgid "Preparing worktree (checking out '%s')" -msgstr "Förbereder arbetskatalog (checkar ut \"%s\")" +msgstr "Förbereder arbetskatalog (checkar ut â€%sâ€)" #, c-format msgid "unreachable: invalid reference: %s" @@ -13297,20 +13419,16 @@ msgid "" "HEAD contents: '%s'" msgstr "" "HEAD pekar pÃ¥ en ogiltig (eller övergiven) referens.\n" -"HEAD-sökväg: \"%s\"\n" -"HEAD-innehÃ¥ll: \"%s\"" +"HEAD-sökväg: â€%sâ€\n" +"HEAD-innehÃ¥ll: â€%sâ€" msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" "Ingen lokal eller fjärr-referens finns trots att Ã¥tminstone en fjärr\n" -"finns, avslutar; använd \"add -f\" för att överstyra eller hämta frÃ¥n en " -"fjärr först" - -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "\"%s\" och \"%s\" kan inte användas samtidigt" +"finns, avslutar; använd â€add -f†för att överstyra eller hämta frÃ¥n en fjärr " +"först" msgid "checkout <branch> even if already checked out in other worktree" msgstr "" @@ -13322,8 +13440,8 @@ msgstr "skapa en ny gren" msgid "create or reset a branch" msgstr "skapa eller Ã¥terställ en gren" -msgid "create unborn/orphaned branch" -msgstr "skapa en ofödd/övergiven gren" +msgid "create unborn branch" +msgstr "skapa en ofödd gren" msgid "populate the new working tree" msgstr "befolka den nya arbetskatalogen" @@ -13342,14 +13460,11 @@ msgstr "försök träffa namn pÃ¥ ny gren mot en fjärrspÃ¥rande gren" #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" -msgstr "flaggorna \"%s\", \"%s\" och \"%s\" kan inte användas samtidigt" +msgstr "flaggorna â€%sâ€, â€%s†och â€%s†kan inte användas samtidigt" #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "flaggorna \"%s\" och \"%s\" kan inte användas samtidigt" - -msgid "<commit-ish>" -msgstr "<incheckning-igt>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "flaggorna â€%s†och incheckning-igt kan inte användas samtidigt" msgid "added with --lock" msgstr "lagt till med --lock" @@ -13361,30 +13476,29 @@ msgid "show extended annotations and reasons, if available" msgstr "visa utökade annoteringar och grunder, om tillgängliga" msgid "add 'prunable' annotation to worktrees older than <time>" -msgstr "" -"lägg till \"prunable\"-annoteringar till arbetskataloger äldre än <tid>" +msgstr "lägg till â€prunableâ€-annoteringar till arbetskataloger äldre än <tid>" msgid "terminate records with a NUL character" msgstr "avsluta poster med NUL-tecken" #, c-format msgid "'%s' is not a working tree" -msgstr "\"%s\" är inte en arbetskatalog" +msgstr "â€%s†är inte en arbetskatalog" msgid "The main working tree cannot be locked or unlocked" msgstr "Huvudarbetskatalogen kan inte lÃ¥sas eller lÃ¥sas upp" #, c-format msgid "'%s' is already locked, reason: %s" -msgstr "\"%s\" är redan lÃ¥st, orsak: %s" +msgstr "â€%s†är redan lÃ¥st, orsak: %s" #, c-format msgid "'%s' is already locked" -msgstr "\"%s\" är redan lÃ¥st" +msgstr "â€%s†är redan lÃ¥st" #, c-format msgid "'%s' is not locked" -msgstr "\"%s\" är inte lÃ¥st" +msgstr "â€%s†är inte lÃ¥st" msgid "working trees containing submodules cannot be moved or removed" msgstr "arbetskataloger med undermoduler kan inte flyttas eller tas bort" @@ -13394,11 +13508,11 @@ msgstr "tvinga flyttning även om arbetskatalogen är smutsig eller lÃ¥st" #, c-format msgid "'%s' is a main working tree" -msgstr "\"%s\" är inte en huvudarbetskatalog" +msgstr "â€%s†är inte en huvudarbetskatalog" #, c-format msgid "could not figure out destination name from '%s'" -msgstr "kunde inte lista ut mÃ¥lnamn frÃ¥n \"%s\"" +msgstr "kunde inte lista ut mÃ¥lnamn frÃ¥n â€%sâ€" #, c-format msgid "" @@ -13406,14 +13520,14 @@ msgid "" "use 'move -f -f' to override or unlock first" msgstr "" "kan inte flytta en lÃ¥st arbetskatalog, orsak till lÃ¥s: %s\n" -"använd \"move -f -f\" för att överstyra, eller lÃ¥s upp först" +"använd â€move -f -f†för att överstyra, eller lÃ¥s upp först" msgid "" "cannot move a locked working tree;\n" "use 'move -f -f' to override or unlock first" msgstr "" "kan inte flytta en lÃ¥st arbetskatalog;\n" -"använd \"move -f -f\" för att överstyra, eller lÃ¥s upp först" +"använd â€move -f -f†för att överstyra, eller lÃ¥s upp först" #, c-format msgid "validation failed, cannot move working tree: %s" @@ -13421,21 +13535,21 @@ msgstr "kontroll misslyckades, kan inte flytta arbetskatalog: %s" #, c-format msgid "failed to move '%s' to '%s'" -msgstr "misslyckades flytta \"%s\" till \"%s\"" +msgstr "misslyckades flytta â€%s†till â€%sâ€" #, c-format msgid "failed to run 'git status' on '%s'" -msgstr "misslyckades köra \"git status\" pÃ¥ \"%s\"" +msgstr "misslyckades köra â€git status†pÃ¥ â€%sâ€" #, c-format msgid "'%s' contains modified or untracked files, use --force to delete it" msgstr "" -"\"%s\" innehÃ¥ller ändrade eller ospÃ¥rade filer, använd --force för att ta " -"bort det" +"â€%s†innehÃ¥ller ändrade eller ospÃ¥rade filer, använd --force för att ta bort " +"det" #, c-format msgid "failed to run 'git status' on '%s', code %d" -msgstr "misslyckades köra \"git status\" pÃ¥ \"%s\", kod %d" +msgstr "misslyckades köra â€git status†pÃ¥ â€%sâ€, kod %d" msgid "force removal even if worktree is dirty or locked" msgstr "tvinga ta bort även om arbetskatalogen är smutsig eller lÃ¥st" @@ -13446,14 +13560,14 @@ msgid "" "use 'remove -f -f' to override or unlock first" msgstr "" "kan inte ta bort en lÃ¥st arbetskatalog, orsak till lÃ¥set: %s\n" -"använd \"remove -f -f\" för att överstyra, eller lÃ¥s upp först" +"använd â€remove -f -f†för att överstyra, eller lÃ¥s upp först" msgid "" "cannot remove a locked working tree;\n" "use 'remove -f -f' to override or unlock first" msgstr "" "kan inte ta bort en lÃ¥st arbetskatalog;\n" -"använd \"remove -f -f\" för att överstyra, eller lÃ¥s upp först" +"använd â€remove -f -f†för att överstyra, eller lÃ¥s upp först" #, c-format msgid "validation failed, cannot remove working tree: %s" @@ -13484,11 +13598,11 @@ msgstr "core.fsyncMethod = batch stöds inte pÃ¥ denna plattform" #, c-format msgid "could not parse bundle list key %s with value '%s'" -msgstr "kunde inte tolka listnyckeln %s med värdet \"%s\"" +msgstr "kunde inte tolka listnyckeln %s med värdet â€%sâ€" #, c-format msgid "bundle list at '%s' has no mode" -msgstr "buntlistan pÃ¥ \"%s\" har inget läge" +msgstr "buntlistan pÃ¥ â€%s†har inget läge" msgid "failed to create temporary file" msgstr "misslyckades skapa temporär fil" @@ -13498,14 +13612,14 @@ msgstr "otillräckliga kapabiliteter" #, c-format msgid "file downloaded from '%s' is not a bundle" -msgstr "filen hämtad frÃ¥n \"%s\" är inte en bunt" +msgstr "filen hämtad frÃ¥n â€%s†är inte en bunt" msgid "failed to store maximum creation token" msgstr "misslyckades lagra maximal skaparsymbol" #, c-format msgid "unrecognized bundle mode from URI '%s'" -msgstr "okänt buntlägre frÃ¥n URI:en \"%s\"" +msgstr "okänt buntlägre frÃ¥n URI:en â€%sâ€" #, c-format msgid "exceeded bundle URI recursion limit (%d)" @@ -13513,35 +13627,35 @@ msgstr "överskred buntens URI-rekursionsgräns (%d)" #, c-format msgid "failed to download bundle from URI '%s'" -msgstr "kunde inte hämta bunt frÃ¥n URI:en \"%s\"" +msgstr "kunde inte hämta bunt frÃ¥n URI:en â€%sâ€" #, c-format msgid "file at URI '%s' is not a bundle or bundle list" -msgstr "filen pÃ¥ URI:en \"%s\" är inte en bunt eller buntlista" +msgstr "filen pÃ¥ URI:en â€%s†är inte en bunt eller buntlista" #, c-format msgid "bundle-uri: unexpected argument: '%s'" -msgstr "bundle-uri: okänt argument: \"%s\"" +msgstr "bundle-uri: okänt argument: â€%sâ€" msgid "bundle-uri: expected flush after arguments" -msgstr "bundle-uri: förväntade \"flush\" efter argument" +msgstr "bundle-uri: förväntade â€flush†efter argument" msgid "bundle-uri: got an empty line" msgstr "bunt-uri: fick en tom rad" msgid "bundle-uri: line is not of the form 'key=value'" -msgstr "bunt-uri: raden är inte pÃ¥ formen \"nyckel=värde\"" +msgstr "bunt-uri: raden är inte pÃ¥ formen â€nyckel=värdeâ€" msgid "bundle-uri: line has empty key or value" msgstr "bunt-uri: raden har tom nyckel eller värde" #, c-format msgid "unrecognized bundle hash algorithm: %s" -msgstr "okänd hashningsalgoritm för bunt: \"%s\"" +msgstr "okänd hashningsalgoritm för bunt: â€%sâ€" #, c-format msgid "unknown capability '%s'" -msgstr "okänd kapabilitet \"%s\"" +msgstr "okänd kapabilitet â€%sâ€" #, c-format msgid "'%s' does not look like a v2 or v3 bundle file" @@ -13598,7 +13712,7 @@ msgstr "pack-objects misslyckades" #, c-format msgid "ref '%s' is excluded by the rev-list options" -msgstr "referensen \"%s\" exkluderas av argumenten till rev-list" +msgstr "referensen â€%s†exkluderas av argumenten till rev-list" #, c-format msgid "unsupported bundle version %d" @@ -13613,7 +13727,7 @@ msgstr "Vägrar skapa en tom bunt." #, c-format msgid "cannot create '%s'" -msgstr "kan inte skapa \"%s\"" +msgstr "kan inte skapa â€%sâ€" msgid "index-pack died" msgstr "index-pack dog" @@ -13622,6 +13736,10 @@ msgid "terminating chunk id appears earlier than expected" msgstr "avslutande stycke-id förekommer tidigare än förväntat" #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "stycke-id %<PRIx32> är inte %d-byte-justerad" + +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "felaktigt stycke-offset %<PRIx64> och %<PRIx64>" @@ -13673,9 +13791,8 @@ msgstr "Samla information frÃ¥n användaren för att sända en felrapport" msgid "Move objects and refs by archive" msgstr "Flytta objekt och referenser efter arkiv" -msgid "Provide content or type and size information for repository objects" -msgstr "" -"Visa innehÃ¥ller eller typ- och storleksinformation för objekt i arkivet" +msgid "Provide contents or details of repository objects" +msgstr "Visa innehÃ¥ll eller detaljer för objekt i arkivet" msgid "Display gitattributes information" msgstr "Visa information frÃ¥n gitattributes" @@ -13960,6 +14077,11 @@ msgstr "Packa opackade objekt i ett arkiv" msgid "Create, list, delete refs to replace objects" msgstr "Skapa, visa, ta bort referenser för att ersätta objekt" +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "" +"EXPERIMENTELLT: Spela om incheckningar ovanpÃ¥ en ny bas, fungerar även med " +"nakna arkiv" + msgid "Generates a summary of pending changes" msgstr "Skapar en sammanfattning av väntande ändringar" @@ -14000,7 +14122,7 @@ msgid "Restricted login shell for Git-only SSH access" msgstr "Begränsat inloggningsskal för SSH-Ã¥tkomst till bara Git" msgid "Summarize 'git log' output" -msgstr "Summera \"git log\"-utdata" +msgstr "Summera â€git logâ€-utdata" msgid "Show various types of objects" msgstr "Visa olika sorters objekt" @@ -14080,8 +14202,8 @@ msgstr "Kontrollera GPG-signaturer i taggar" msgid "Display version information about Git" msgstr "Visa versionsinformation om Git" -msgid "Show logs with difference each commit introduces" -msgstr "Visa loggar med differenser varje incheckning introducerar" +msgid "Show logs with differences each commit introduces" +msgstr "Visa loggar med ändringarna varje incheckning introducerar" msgid "Manage multiple working trees" msgstr "Hantera ytterligare arbetskataloger" @@ -14197,6 +14319,32 @@ msgstr "Verktyg för att hantera stora Git-arkiv" msgid "commit-graph file is too small" msgstr "incheckningsgraffilen %s är för liten" +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "incheckningsgrafens oid-utbredningsstycke har fel storlek" + +msgid "commit-graph fanout values out of order" +msgstr "incheckningsgrafens utbredningsvärden är i fel ordning" + +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "incheckningsgrafens OID-uppslagningsstycket har fel storlek" + +msgid "commit-graph commit data chunk is wrong size" +msgstr "incheckningsgrafens incheckningsdatastycke har fel storlek" + +msgid "commit-graph generations chunk is wrong size" +msgstr "incheckningsgrafens generationsstycke har fel storlek" + +msgid "commit-graph changed-path index chunk is too small" +msgstr "incheckningsgrafens ändrade-sökvägar-indexstycke är förö litet" + +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "" +"ignorerar för litet ändrade-sökvägar-stycke (%<PRIuMAX> < %<PRIuMAX>) i " +"incheckningsgraffilen" + #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "incheckningsgrafens signatur %X stämmer inte med signaturen %X" @@ -14213,9 +14361,24 @@ msgstr "incheckningsgrafens hashversion %X stämmer inte med versionen %X" msgid "commit-graph file is too small to hold %u chunks" msgstr "incheckningsgraffilen är för liten för att innehÃ¥lla %u stycken" +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "" +"incheckningsgrafens nödvändiga OID-utbredningsstycke saknas eller är trasigt" + +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "" +"incheckningsgrafens nödvändiga OID-uppslagningsstycke saknas eller är trasigt" + +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "" +"incheckningsgrafens nödvändiga incheckningsdatastycke saknas eller är trasigt" + msgid "commit-graph has no base graphs chunk" msgstr "incheckningsgrafen har inga bas-graf-stycken" +msgid "commit-graph base graphs chunk is too small" +msgstr "incheckningsgrafens bas-graf-stycken är för smÃ¥" + msgid "commit-graph chain does not match" msgstr "incheckningsgrafens kedja stämmer inte" @@ -14223,9 +14386,12 @@ msgstr "incheckningsgrafens kedja stämmer inte" msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "antalet incheckningar i basgrafen för högt: %<PRIuMAX>" +msgid "commit-graph chain file too small" +msgstr "incheckningsgrafens kedjefil är för liten" + #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" -msgstr "ogiltig incheckingsgrafkedja: rad \"%s\" är inte ett hash-värde" +msgstr "ogiltig incheckingsgrafkedja: rad â€%s†är inte ett hash-värde" msgid "unable to find all commit-graph files" msgstr "kan inte hitta alla incheckingsgraffiler" @@ -14240,6 +14406,12 @@ msgstr "kunde inte hitta incheckningen %s" msgid "commit-graph requires overflow generation data but has none" msgstr "incheckningsgraf kräver spillgenerationsdata, men har ingen" +msgid "commit-graph overflow generation data is too small" +msgstr "incheckningsgrafens spillgenerationsdata är för liten" + +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "incheckningsgrafens extra-kant-pekare är utanför intervallet" + msgid "Loading known commits in commit graph" msgstr "Läser in kända incheckningar i incheckningsgraf" @@ -14289,7 +14461,7 @@ msgstr "kan inte skapa temporärt graflager" #, c-format msgid "unable to adjust shared permissions for '%s'" -msgstr "kan inte justera delade behörigheter för \"%s\"" +msgstr "kan inte justera delade behörigheter för â€%sâ€" #, c-format msgid "Writing out commit graph in %d pass" @@ -14322,7 +14494,7 @@ msgstr "SlÃ¥r ihop incheckningsgraf" msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled" msgstr "" -"försöker skriva en incheckningsgraf, men \"core.commitGraph\" är inaktiverad" +"försöker skriva en incheckningsgraf, men â€core.commitGraph†är inaktiverad" msgid "too many commits to write graph" msgstr "för mÃ¥nga incheckningar för att skriva graf" @@ -14368,20 +14540,6 @@ msgstr "" "incheckningsgrafens föräldralista för incheckningen %s avslutas för tidigt" #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" -"incheckningsgrafen har generationsnummer noll för incheckningen %s, men icke-" -"noll pÃ¥ annan plats" - -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" -"incheckningsgrafen har generationsnummer skilt frÃ¥n noll för incheckningen " -"%s, men noll pÃ¥ annan plats" - -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "" "incheckningsgrafens generation för incheckningen %s är %<PRIuMAX> < " @@ -14393,6 +14551,14 @@ msgstr "" "incheckningsdatumet för incheckningen %s i incheckningsgrafen är %<PRIuMAX> !" "= %<PRIuMAX>" +#, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "" +"incheckningsgrafen har generationsnummer som bÃ¥de är noll och icke-noll " +"(dvs, incheckningarna â€%s†och â€%sâ€)" + msgid "Verifying commits in commit graph" msgstr "Bekräftar incheckningar i incheckningsgrafen" @@ -14413,11 +14579,16 @@ msgstr "" "Stöd för <GIT_DIR>/info/grafts avrÃ¥ds frÃ¥n och\n" "kommer tas bort i en framtida version av Git.\n" "\n" -"Använd \"git replace --convert-graft-file\"\n" +"Använd â€git replace --convert-graft-fileâ€\n" "för att omvandla grafts till ersättningsreferenser.\n" "\n" "SlÃ¥ av detta meddelande genom att skriva\n" -"\"git config advice.graftFileDeprecated false\"" +"â€git config advice.graftFileDeprecated falseâ€" + +#, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "" +"incheckningen %s finns i incheckningsgrafen, men inte i objektdatabasen" #, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." @@ -14454,31 +14625,31 @@ msgstr "ingen libc-information tillgänglig\n" #, c-format msgid "could not determine free disk size for '%s'" -msgstr "kunde inte ta reda pÃ¥ ledigt diskutrymme för \"%s\"" +msgstr "kunde inte ta reda pÃ¥ ledigt diskutrymme för â€%sâ€" #, c-format msgid "could not get info for '%s'" -msgstr "kunde inte hämta info för \"%s\"" +msgstr "kunde inte hämta info för â€%sâ€" #, c-format msgid "[GLE %ld] health thread could not open '%ls'" -msgstr "[GLE %ld] hälsotrÃ¥den kunde inte öppna \"%ls\"" +msgstr "[GLE %ld] hälsotrÃ¥den kunde inte öppna â€%lsâ€" #, c-format msgid "[GLE %ld] health thread getting BHFI for '%ls'" -msgstr "[GLE %ld] hälsotrÃ¥den hämtar BHFI för \"%ls\"" +msgstr "[GLE %ld] hälsotrÃ¥den hämtar BHFI för â€%lsâ€" #, c-format msgid "could not convert to wide characters: '%s'" -msgstr "kunde inte konvertera till breda tecken: \"%s\"" +msgstr "kunde inte konvertera till breda tecken: â€%sâ€" #, c-format msgid "BHFI changed '%ls'" -msgstr "BHFI ändrade \"%ls\"" +msgstr "BHFI ändrade â€%lsâ€" #, c-format msgid "unhandled case in 'has_worktree_moved': %d" -msgstr "ohanterat fall i \"has_worktree_moved\": %d" +msgstr "ohanterat fall i â€has_worktree_movedâ€: %d" #, c-format msgid "health thread wait failed [GLE %ld]" @@ -14496,23 +14667,23 @@ msgstr "Misslyckades starta FSEventStream:en" #, c-format msgid "[GLE %ld] could not convert path to UTF-8: '%.*ls'" -msgstr "[GLE %ld] kunde inte konvertera sökväg till UTF-8: \"%.*ls\"" +msgstr "[GLE %ld] kunde inte konvertera sökväg till UTF-8: â€%.*lsâ€" #, c-format msgid "[GLE %ld] could not watch '%s'" -msgstr "[GLE %ld] kunde inte övervaka \"%s\"" +msgstr "[GLE %ld] kunde inte övervaka â€%sâ€" #, c-format msgid "[GLE %ld] could not get longname of '%s'" -msgstr "[GLE %ld] kunde inte hämta lÃ¥ngt namn för \"%s\"" +msgstr "[GLE %ld] kunde inte hämta lÃ¥ngt namn för â€%sâ€" #, c-format msgid "ReadDirectoryChangedW failed on '%s' [GLE %ld]" -msgstr "ReadDirectoryChangedW misslyckades pÃ¥ \"%s\" [GLE %ld]" +msgstr "ReadDirectoryChangedW misslyckades pÃ¥ â€%s†[GLE %ld]" #, c-format msgid "GetOverlappedResult failed on '%s' [GLE %ld]" -msgstr "GetOverlappedResult misslyckades pÃ¥ \"%s\" [GLE %ld]" +msgstr "GetOverlappedResult misslyckades pÃ¥ â€%s†[GLE %ld]" #, c-format msgid "could not read directory changes [GLE %ld]" @@ -14536,11 +14707,11 @@ msgstr "closedir('%s') misslyckades" #, c-format msgid "[GLE %ld] unable to open for read '%ls'" -msgstr "[GLE %ld] kunde inte öppna \"%ls\" för läsning" +msgstr "[GLE %ld] kunde inte öppna â€%ls†för läsning" #, c-format msgid "[GLE %ld] unable to get protocol information for '%ls'" -msgstr "[GLE %ld] kunde inte hämta protokollinformation för \"%ls\"" +msgstr "[GLE %ld] kunde inte hämta protokollinformation för â€%lsâ€" #, c-format msgid "failed to copy SID (%ld)" @@ -14548,7 +14719,7 @@ msgstr "misslyckades kopiera SID (%ld)" #, c-format msgid "failed to get owner for '%s' (%ld)" -msgstr "misslyckades hämta ägaren för \"%s\" (%ld)" +msgstr "misslyckades hämta ägaren för â€%s†(%ld)" msgid "memory exhausted" msgstr "minnet slut" @@ -14615,15 +14786,15 @@ msgstr "kunde inte läsa IPC-svar" #, c-format msgid "could not start accept_thread '%s'" -msgstr "kunde inte ta status \"accept_thread\" \"%s\"" +msgstr "kunde inte ta status â€accept_thread†â€%sâ€" #, c-format msgid "could not start worker[0] for '%s'" -msgstr "kunde inte starta \"worker[0]\" för \"%s\"" +msgstr "kunde inte starta â€worker[0]†för â€%sâ€" #, c-format msgid "ConnectNamedPipe failed for '%s' (%lu)" -msgstr "ConnectNamedPipe misslyckades för \"%s\" (%lu)" +msgstr "ConnectNamedPipe misslyckades för â€%s†(%lu)" #, c-format msgid "could not create fd from pipe for '%s'" @@ -14631,14 +14802,14 @@ msgstr "kunde inte skapa filhandtag frÃ¥n rör för %s" #, c-format msgid "could not start thread[0] for '%s'" -msgstr "kunde inte starta thread[0] för \"%s\"" +msgstr "kunde inte starta thread[0] för â€%sâ€" #, c-format msgid "wait for hEvent failed for '%s'" -msgstr "misslyckades vänta pÃ¥ hEvent för \"%s\"" +msgstr "misslyckades vänta pÃ¥ hEvent för â€%sâ€" msgid "cannot resume in the background, please use 'fg' to resume" -msgstr "kan inte fortsätta i bakgrunden, använd \"fg\" för att Ã¥teruppta" +msgstr "kan inte fortsätta i bakgrunden, använd â€fg†för att Ã¥teruppta" msgid "cannot restore terminal settings" msgstr "kan inte Ã¥terställa terminalinställningar" @@ -14659,7 +14830,7 @@ msgstr "" #, c-format msgid "could not expand include path '%s'" -msgstr "kunde inte expandera inkluderingssökväg \"%s\"" +msgstr "kunde inte expandera inkluderingssökväg â€%sâ€" msgid "relative config includes must come from files" msgstr "relativa konfigureringsinkluderingar mÃ¥ste komma frÃ¥n filer" @@ -14680,11 +14851,11 @@ msgstr "felaktigt konfigurationsformat: %s" #, c-format msgid "missing environment variable name for configuration '%.*s'" -msgstr "miljövariabelnamn saknas för konfigurationen \"%.*s\"" +msgstr "miljövariabelnamn saknas för konfigurationen â€%.*sâ€" #, c-format msgid "missing environment variable '%s' for configuration '%.*s'" -msgstr "miljövariabeln \"%s\" saknas för konfigurationen \"%.*s\"" +msgstr "miljövariabeln â€%s†saknas för konfigurationen â€%.*sâ€" #, c-format msgid "key does not contain a section: %s" @@ -14761,38 +14932,35 @@ msgstr "ogiltig enhet" #, c-format msgid "bad numeric config value '%s' for '%s': %s" -msgstr "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\": %s" +msgstr "felaktigt numeriskt konfigurationsvärde â€%s†för â€%sâ€: %s" #, c-format msgid "bad numeric config value '%s' for '%s' in blob %s: %s" -msgstr "" -"felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i blob:en %s: %s" +msgstr "felaktigt numeriskt konfigurationsvärde â€%s†för â€%s†i blob:en %s: %s" #, c-format msgid "bad numeric config value '%s' for '%s' in file %s: %s" -msgstr "" -"felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i filen %s: %s" +msgstr "felaktigt numeriskt konfigurationsvärde â€%s†för â€%s†i filen %s: %s" #, c-format msgid "bad numeric config value '%s' for '%s' in standard input: %s" msgstr "" -"felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i standard in: %s" +"felaktigt numeriskt konfigurationsvärde â€%s†för â€%s†i standard in: %s" #, c-format msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s" msgstr "" -"felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i undermodul-blob:" -"en %s: %s" +"felaktigt numeriskt konfigurationsvärde â€%s†för â€%s†i undermodul-blob:en " +"%s: %s" #, c-format msgid "bad numeric config value '%s' for '%s' in command line %s: %s" msgstr "" -"felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i kommandoraden " -"%s: %s" +"felaktigt numeriskt konfigurationsvärde â€%s†för â€%s†i kommandoraden %s: %s" #, c-format msgid "bad numeric config value '%s' for '%s' in %s: %s" -msgstr "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i %s: %s" +msgstr "felaktigt numeriskt konfigurationsvärde â€%s†för â€%s†i %s: %s" #, c-format msgid "invalid value for variable %s" @@ -14800,19 +14968,19 @@ msgstr "ogiltigt värde för variabeln %s" #, c-format msgid "ignoring unknown core.fsync component '%s'" -msgstr "ignorerar okänd core.fsync-komponent \"%s\"" +msgstr "ignorerar okänd core.fsync-komponent â€%sâ€" #, c-format msgid "bad boolean config value '%s' for '%s'" -msgstr "felaktigt booleskt konfigurationsvärde \"%s\" för \"%s\"" +msgstr "felaktigt booleskt konfigurationsvärde â€%s†för â€%sâ€" #, c-format msgid "failed to expand user dir in: '%s'" -msgstr "misslyckades expandera användarkatalog i: \"%s\"" +msgstr "misslyckades expandera användarkatalog i: â€%sâ€" #, c-format msgid "'%s' for '%s' is not a valid timestamp" -msgstr "\"%s\" för \"%s\" är inte en giltig tidsstämpel" +msgstr "â€%s†för â€%s†är inte en giltig tidsstämpel" #, c-format msgid "abbrev length out of range: %d" @@ -14827,7 +14995,7 @@ msgstr "core.commentChar kan bara vara ett ASCII-tecken" #, c-format msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "ignorerar okänt core.fsyncMethod-värde \"%s\"" +msgstr "ignorerar okänt core.fsyncMethod-värde â€%sâ€" msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" msgstr "core.fsyncObjectFiles avrÃ¥ds frÃ¥n; använd core.fsync istället" @@ -14849,19 +15017,15 @@ msgstr "mÃ¥ste vara en av nothing, matching, simple, upstream eller current" #, c-format msgid "unable to load config blob object '%s'" -msgstr "kunde inte läsa konfigurerings-blobobjektet \"%s\"" +msgstr "kunde inte läsa konfigurerings-blobobjektet â€%sâ€" #, c-format msgid "reference '%s' does not point to a blob" -msgstr "referensen \"%s\" pekar inte pÃ¥ en blob" +msgstr "referensen â€%s†pekar inte pÃ¥ en blob" #, c-format msgid "unable to resolve config blob '%s'" -msgstr "kan inte slÃ¥ upp konfigurerings-bloben \"%s\"" - -#, c-format -msgid "failed to parse %s" -msgstr "kunde inte tolka %s" +msgstr "kan inte slÃ¥ upp konfigurerings-bloben â€%sâ€" msgid "unable to parse command-line config" msgstr "kan inte tolka kommandoradskonfiguration" @@ -14871,24 +15035,24 @@ msgstr "okänt fel uppstod vid läsning av konfigurationsfilerna" #, c-format msgid "Invalid %s: '%s'" -msgstr "Felaktigt %s: \"%s\"" +msgstr "Felaktigt %s: â€%sâ€" #, c-format msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100" msgstr "" -"värdet \"%d\" för splitIndex.maxPercentChange borde vara mellan 0 och 100" +"värdet â€%d†för splitIndex.maxPercentChange borde vara mellan 0 och 100" #, c-format msgid "unable to parse '%s' from command-line config" -msgstr "kunde inte tolka värdet \"%s\" frÃ¥n kommandoradskonfiguration" +msgstr "kunde inte tolka värdet â€%s†frÃ¥n kommandoradskonfiguration" #, c-format msgid "bad config variable '%s' in file '%s' at line %d" -msgstr "felaktig konfigurationsvariabel \"%s\" i filen \"%s\" pÃ¥ rad %d" +msgstr "felaktig konfigurationsvariabel â€%s†i filen â€%s†pÃ¥ rad %d" #, c-format msgid "invalid section name '%s'" -msgstr "felaktigt sektionsnamn \"%s\"" +msgstr "felaktigt sektionsnamn â€%sâ€" #, c-format msgid "%s has multiple values" @@ -14896,7 +15060,7 @@ msgstr "%s har flera värden" #, c-format msgid "failed to write new configuration file %s" -msgstr "kan inte skriva nya konfigurationsfilen \"%s\"" +msgstr "kan inte skriva nya konfigurationsfilen â€%sâ€" #, c-format msgid "could not lock config file %s" @@ -14908,7 +15072,7 @@ msgstr "öppnar %s" #, c-format msgid "invalid config file %s" -msgstr "ogiltig konfigurationsfil: \"%s\"" +msgstr "ogiltig konfigurationsfil: â€%sâ€" #, c-format msgid "fstat on %s failed" @@ -14916,7 +15080,7 @@ msgstr "fstat misslyckades pÃ¥ %s" #, c-format msgid "unable to mmap '%s'%s" -msgstr "kunde inte utföra mmap pÃ¥ \"%s\"%s" +msgstr "kunde inte utföra mmap pÃ¥ â€%sâ€%s" #, c-format msgid "chmod on %s failed" @@ -14928,7 +15092,7 @@ msgstr "kunde inte skriva konfigurationsfilen %s" #, c-format msgid "could not set '%s' to '%s'" -msgstr "kunde inte ställa in \"%s\" till \"%s\"" +msgstr "kunde inte ställa in â€%s†till â€%sâ€" #, c-format msgid "invalid section name: %s" @@ -14936,11 +15100,11 @@ msgstr "felaktigt namn pÃ¥ stycke: %s" #, c-format msgid "refusing to work with overly long line in '%s' on line %<PRIuMAX>" -msgstr "vägrar arbeta med för lÃ¥nga rader i \"%s\" pÃ¥ rad %<PRIuMAX>" +msgstr "vägrar arbeta med för lÃ¥nga rader i â€%s†pÃ¥ rad %<PRIuMAX>" #, c-format msgid "missing value for '%s'" -msgstr "värde saknas för \"%s\"" +msgstr "värde saknas för â€%sâ€" msgid "the remote end hung up upon initial contact" msgstr "fjärren lade pÃ¥ vid inledande kontakt" @@ -14958,25 +15122,25 @@ msgstr "" #, c-format msgid "server doesn't support '%s'" -msgstr "Servern stöder inte \"%s\"" +msgstr "Servern stöder inte â€%sâ€" #, c-format msgid "server doesn't support feature '%s'" -msgstr "servern stöder inte funktionen \"%s\"" +msgstr "servern stöder inte funktionen â€%sâ€" msgid "expected flush after capabilities" -msgstr "förväntade \"flush\" efter förmÃ¥gor" +msgstr "förväntade â€flush†efter förmÃ¥gor" #, c-format msgid "ignoring capabilities after first line '%s'" -msgstr "ignorerar förmÃ¥gor efter första raden \"%s\"" +msgstr "ignorerar förmÃ¥gor efter första raden â€%sâ€" msgid "protocol error: unexpected capabilities^{}" msgstr "protokollfel: förväntade inte capabilities^{}" #, c-format msgid "protocol error: expected shallow sha-1, got '%s'" -msgstr "protokollfel: förväntade \"shallow sha-1\" fick \"%s\"" +msgstr "protokollfel: förväntade â€shallow sha-1†fick â€%sâ€" msgid "repository on the other end cannot be shallow" msgstr "arkivet pÃ¥ andra sidan kan inte vara grunt" @@ -14986,18 +15150,18 @@ msgstr "ogiltigt paket" #, c-format msgid "protocol error: unexpected '%s'" -msgstr "protokollfel: förväntade inte \"%s\"" +msgstr "protokollfel: förväntade inte â€%sâ€" #, c-format msgid "unknown object format '%s' specified by server" -msgstr "okänt objektformat \"%s\" angavs av servern" +msgstr "okänt objektformat â€%s†angavs av servern" #, c-format msgid "error on bundle-uri response line %d: %s" msgstr "fel pÃ¥ bundle-uri-svar rad %d: %s" msgid "expected flush after bundle-uri listing" -msgstr "förväntade \"flush\" efter bundle-uri-listan" +msgstr "förväntade â€flush†efter bundle-uri-listan" msgid "expected response end packet after ref listing" msgstr "förväntade svarsavslutningspaket efter ref-listan" @@ -15007,11 +15171,11 @@ msgid "invalid ls-refs response: %s" msgstr "ogiltigt svar pÃ¥ ls-refs: %s" msgid "expected flush after ref listing" -msgstr "förväntade \"flush\" efter ref-listan" +msgstr "förväntade â€flush†efter ref-listan" #, c-format msgid "protocol '%s' is not supported" -msgstr "protokollet \"%s\" stöds inte" +msgstr "protokollet â€%s†stöds inte" msgid "unable to set SO_KEEPALIVE on socket" msgstr "kunde inte sätta SO_KEEPALIVE pÃ¥ uttaget" @@ -15055,40 +15219,40 @@ msgstr "okänd port %s" #, c-format msgid "strange hostname '%s' blocked" -msgstr "konstigt värdnamn \"%s\" blockerat" +msgstr "konstigt värdnamn â€%s†blockerat" #, c-format msgid "strange port '%s' blocked" -msgstr "konstig port \"%s\" blockerad" +msgstr "konstig port â€%s†blockerad" #, c-format msgid "cannot start proxy %s" msgstr "kan inte starta mellanserver (proxy) %s" msgid "no path specified; see 'git help pull' for valid url syntax" -msgstr "ingen sökväg angavs; se \"git help pull\" för giltig URL-syntax" +msgstr "ingen sökväg angavs; se â€git help pull†för giltig URL-syntax" msgid "newline is forbidden in git:// hosts and repo paths" msgstr "radbrytningar är förbjudna i git://-värdnamn och arkivsökvägar" msgid "ssh variant 'simple' does not support -4" -msgstr "ssh-varianten \"simple\" stöder inte -4" +msgstr "ssh-varianten â€simple†stöder inte -4" msgid "ssh variant 'simple' does not support -6" -msgstr "ssh-varianten \"simple\" stöder inte -6" +msgstr "ssh-varianten â€simple†stöder inte -6" msgid "ssh variant 'simple' does not support setting port" -msgstr "ssh-varianten \"simple\" stöder inte val av port" +msgstr "ssh-varianten â€simple†stöder inte val av port" #, c-format msgid "strange pathname '%s' blocked" -msgstr "konstigt sökvägsnamn \"%s\" blockerat" +msgstr "konstigt sökvägsnamn â€%s†blockerat" msgid "unable to fork" msgstr "kunde inte grena (fork)" msgid "Could not run 'git rev-list'" -msgstr "Kunde inte köra \"git rev-list\"" +msgstr "Kunde inte köra â€git rev-listâ€" msgid "failed write to rev-list" msgstr "kunde inte skriva till rev-list" @@ -15109,7 +15273,7 @@ msgid "" "in the working copy of '%s', CRLF will be replaced by LF the next time Git " "touches it" msgstr "" -"CRLF i arbetskopian av \"%s\" kommer ersättas med LF nästa gÃ¥ng Git rör den" +"CRLF i arbetskopian av â€%s†kommer ersättas med LF nästa gÃ¥ng Git rör den" #, c-format msgid "LF would be replaced by CRLF in %s" @@ -15120,60 +15284,59 @@ msgid "" "in the working copy of '%s', LF will be replaced by CRLF the next time Git " "touches it" msgstr "" -"LF i arbetskopian av \"%s\" kommer ersättas med CRLF nästa gÃ¥ng Git rör den" +"LF i arbetskopian av â€%s†kommer ersättas med CRLF nästa gÃ¥ng Git rör den" #, c-format msgid "BOM is prohibited in '%s' if encoded as %s" -msgstr "BOM är förbjudet i \"%s\" om kodat som %s" +msgstr "BOM är förbjudet i â€%s†om kodat som %s" #, c-format msgid "" "The file '%s' contains a byte order mark (BOM). Please use UTF-%.*s as " "working-tree-encoding." msgstr "" -"Filen \"%s\" innehÃ¥ller byte order mark (BOM). Använd UTF-%.*s som " +"Filen â€%s†innehÃ¥ller byte order mark (BOM). Använd UTF-%.*s som " "teckenkodning i arbetskatalogen." #, c-format msgid "BOM is required in '%s' if encoded as %s" -msgstr "BOM krävs om \"%s\" kodas som %s" +msgstr "BOM krävs om â€%s†kodas som %s" #, 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 "" -"Filen \"%s\" saknar byte order mark (BOM). Använd UTF-%sBE eller UTF-%sLE " +"Filen â€%s†saknar byte order mark (BOM). Använd UTF-%sBE eller UTF-%sLE " "(beroende pÃ¥ byteordning) som teckenkodning i arbetskatalogen." #, c-format msgid "failed to encode '%s' from %s to %s" -msgstr "misslyckades omkoda \"%s\" frÃ¥n %s till %s" +msgstr "misslyckades omkoda â€%s†frÃ¥n %s till %s" #, c-format msgid "encoding '%s' from %s to %s and back is not the same" -msgstr "" -"omkodning av \"%s\" frÃ¥n %s till %s och tillbaka ger inte samma resultat" +msgstr "omkodning av â€%s†frÃ¥n %s till %s och tillbaka ger inte samma resultat" #, c-format msgid "cannot fork to run external filter '%s'" -msgstr "kan inte grena (fork) för att köra externt filter \"%s\"" +msgstr "kan inte grena (fork) för att köra externt filter â€%sâ€" #, c-format msgid "cannot feed the input to external filter '%s'" -msgstr "kunde inte skicka indata till externt filter \"%s\"" +msgstr "kunde inte skicka indata till externt filter â€%sâ€" #, c-format msgid "external filter '%s' failed %d" -msgstr "externt filter \"%s\" misslyckades %d" +msgstr "externt filter â€%s†misslyckades %d" #, c-format msgid "read from external filter '%s' failed" -msgstr "läsning frÃ¥n externt filter \"%s\" misslyckades" +msgstr "läsning frÃ¥n externt filter â€%s†misslyckades" #, c-format msgid "external filter '%s' failed" -msgstr "externt filter \"%s\" misslyckades" +msgstr "externt filter â€%s†misslyckades" msgid "unexpected filter type" msgstr "oväntad filtertyp" @@ -15186,19 +15349,19 @@ msgid "" "external filter '%s' is not available anymore although not all paths have " "been filtered" msgstr "" -"externt filter \"%s\" är inte längre tillgängligt trots att alla sökvägar " -"inte har filtrerats" +"externt filter â€%s†är inte längre tillgängligt trots att alla sökvägar inte " +"har filtrerats" msgid "true/false are no valid working-tree-encodings" msgstr "true/false är inte giltig teckenkodning för arbetskatalogen" #, c-format msgid "%s: clean filter '%s' failed" -msgstr "%s: \"clean\"-filtret \"%s\" misslyckades" +msgstr "%s: â€cleanâ€-filtret â€%s†misslyckades" #, c-format msgid "%s: smudge filter %s failed" -msgstr "%s: \"smudge\"-filtret \"%s\" misslyckades" +msgstr "%s: â€smudgeâ€-filtret â€%s†misslyckades" #, c-format msgid "skipping credential lookup for key: credential.%s" @@ -15289,7 +15452,7 @@ msgstr "felaktigt trädobjektet %s" #, c-format msgid "failed to load island regex for '%s': %s" -msgstr "kunde inte hämta ö-regex för \"%s\": %s" +msgstr "kunde inte hämta ö-regex för â€%sâ€: %s" #, c-format msgid "island regex from config has too many capture groups (max=%d)" @@ -15301,26 +15464,26 @@ msgstr "Markerade %d öar, klar.\n" #, c-format msgid "invalid --%s value '%s'" -msgstr "ogiltigt värde för --%s: \"%s\"" +msgstr "ogiltigt värde för --%s: â€%sâ€" #, c-format msgid "could not archive missing directory '%s'" -msgstr "kunde inte arkivera saknad katalog \"%s\"" +msgstr "kunde inte arkivera saknad katalog â€%sâ€" #, c-format msgid "could not open directory '%s'" -msgstr "kunde inte öppna katalogen \"%s\"" +msgstr "kunde inte öppna katalogen â€%sâ€" #, c-format msgid "skipping '%s', which is neither file nor directory" -msgstr "hoppar över \"%s\", som varken är en fil eller en katalog" +msgstr "hoppar över â€%sâ€, som varken är en fil eller en katalog" msgid "could not duplicate stdout" msgstr "kunde inte duplicera standard ut" #, c-format msgid "could not add directory '%s' to archiver" -msgstr "kunde inte lägga till katalogen \"%s\" till arkiveraren" +msgstr "kunde inte lägga till katalogen â€%s†till arkiveraren" msgid "failed to write archive" msgstr "misslyckades skriva arkiv" @@ -15328,9 +15491,6 @@ msgstr "misslyckades skriva arkiv" msgid "--merge-base does not work with ranges" msgstr "--merge-base fungerar inte med intervall" -msgid "--merge-base only works with commits" -msgstr "--merge-base fungerar bara med incheckningar" - msgid "unable to get HEAD" msgstr "kan inte hämta HEAD" @@ -15358,27 +15518,26 @@ msgstr "" #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" -msgstr " Misslyckades tolka dirstat-avskärningsprocentandel \"%s\"\n" +msgstr " Misslyckades tolka dirstat-avskärningsprocentandel â€%sâ€\n" #, c-format msgid " Unknown dirstat parameter '%s'\n" -msgstr " Okänd dirstat-parameter \"%s\"\n" +msgstr " Okänd dirstat-parameter â€%sâ€\n" msgid "" "color moved setting must be one of 'no', 'default', 'blocks', 'zebra', " "'dimmed-zebra', 'plain'" msgstr "" -"färginställningen för flyttade block mÃ¥ste vara en av \"no\", \"default\", " -"\"blocks\", \"zebra\", \"dimmed-zebra\", \"plain\"" +"färginställningen för flyttade block mÃ¥ste vara en av â€noâ€, â€defaultâ€, " +"â€blocksâ€, â€zebraâ€, â€dimmed-zebraâ€, â€plainâ€" #, 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 "" -"okänt läge \"%s\" för color-moved-ws, möjliga värden är \"ignore-space-change" -"\", \"ignore-space-at-eol\", \"ignore-all-space\", \"allow-indentation-change" -"\"" +"okänt läge â€%s†för color-moved-ws, möjliga värden är â€ignore-space-changeâ€, " +"â€ignore-space-at-eolâ€, â€ignore-all-spaceâ€, â€allow-indentation-changeâ€" msgid "" "color-moved-ws: allow-indentation-change cannot be combined with other " @@ -15389,14 +15548,18 @@ msgstr "" #, c-format msgid "Unknown value for 'diff.submodule' config variable: '%s'" -msgstr "Okänt värde för konfigurationsvariabeln \"diff.submodule\": \"%s\"" +msgstr "Okänt värde för konfigurationsvariabeln â€diff.submoduleâ€: â€%sâ€" + +#, c-format +msgid "unknown value for config '%s': %s" +msgstr "okänt värde för inställningen â€%sâ€: %s" #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" msgstr "" -"Hittade fel i konfigurationsvariabeln \"diff.dirstat\":\n" +"Hittade fel i konfigurationsvariabeln â€diff.dirstatâ€:\n" "%s" #, c-format @@ -15412,21 +15575,19 @@ msgstr "sökvägs-magi stöds inte av --follow: %s" #, c-format msgid "options '%s', '%s', '%s', and '%s' cannot be used together" -msgstr "" -"flaggorna \"%s\", \"%s\", \"%s\" och \"%s\" kan inte användas samtidigt" +msgstr "flaggorna â€%sâ€, â€%sâ€, â€%s†och â€%s†kan inte användas samtidigt" #, c-format msgid "options '%s' and '%s' cannot be used together, use '%s' with '%s'" msgstr "" -"flaggorna \"%s\" och \"%s\" kan inte användas samtidigt, använd \"%s\" med " -"\"%s\"" +"flaggorna â€%s†och â€%s†kan inte användas samtidigt, använd â€%s†med â€%sâ€" #, c-format msgid "" "options '%s' and '%s' cannot be used together, use '%s' with '%s' and '%s'" msgstr "" -"flaggorna \"%s\" och \"%s\" kan inte användas samtidigt, använd \"%s\" med " -"\"%s\" och \"%s\"" +"flaggorna â€%s†och â€%s†kan inte användas samtidigt, använd â€%s†med â€%s†" +"och â€%sâ€" #, c-format msgid "invalid --stat value: %s" @@ -15446,7 +15607,7 @@ msgstr "" #, c-format msgid "unknown change class '%c' in --diff-filter=%s" -msgstr "okänd ändringsklass \"%c\" i --diff-filter=%s" +msgstr "okänd ändringsklass â€%c†i --diff-filter=%s" #, c-format msgid "unknown value after ws-error-highlight=%.*s" @@ -15454,7 +15615,7 @@ msgstr "okänt värde efter ws-error-highlight=%.*s" #, c-format msgid "unable to resolve '%s'" -msgstr "kunde inte slÃ¥ upp \"%s\"" +msgstr "kunde inte slÃ¥ upp â€%sâ€" #, c-format msgid "%s expects <n>/<m> form" @@ -15462,7 +15623,7 @@ msgstr "%s förväntar formen <n>/<m>" #, c-format msgid "%s expects a character, got '%s'" -msgstr "%s förväntar ett tecken, fick \"%s\"" +msgstr "%s förväntar ett tecken, fick â€%sâ€" #, c-format msgid "bad --color-moved argument: %s" @@ -15470,14 +15631,7 @@ msgstr "felaktigt argument till --color-moved: %s" #, c-format msgid "invalid mode '%s' in --color-moved-ws" -msgstr "ogiltigt läge %s\" i --color-moved-ws" - -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"flaggan diff-algorithm godtar\"myers\", \"minimal\", \"patience\" och " -"\"histogram\"" +msgstr "ogiltigt läge %s†i --color-moved-ws" #, c-format msgid "invalid argument to %s" @@ -15485,11 +15639,11 @@ msgstr "ogiltigt argument för %s" #, c-format msgid "invalid regex given to -I: '%s'" -msgstr "ogiltigt reguljärt uttryck angavs för -I: \"%s\"" +msgstr "ogiltigt reguljärt uttryck angavs för -I: â€%sâ€" #, c-format msgid "failed to parse --submodule option parameter: '%s'" -msgstr "misslyckades tolka argument till flaggan --submodule: \"%s\"" +msgstr "misslyckades tolka argument till flaggan --submodule: â€%sâ€" #, c-format msgid "bad --word-diff argument: %s" @@ -15511,10 +15665,10 @@ msgid "generate the diff in raw format" msgstr "generera diff i rÃ¥format" msgid "synonym for '-p --raw'" -msgstr "synonym till \"-p --raw\"" +msgstr "synonym till â€-p --rawâ€" msgid "synonym for '-p --stat'" -msgstr "synonym till \"-p --stat\"" +msgstr "synonym till â€-p --statâ€" msgid "machine friendly --stat" msgstr "maskinläsbar --stat" @@ -15522,8 +15676,8 @@ msgstr "maskinläsbar --stat" msgid "output only the last line of --stat" msgstr "skriv bara ut den sista raden för --stat" -msgid "<param1,param2>..." -msgstr "<param1,param2>..." +msgid "<param1>,<param2>..." +msgstr "<param1>,<param2>..." msgid "" "output the distribution of relative amount of changes for each sub-directory" @@ -15533,8 +15687,8 @@ msgstr "" msgid "synonym for --dirstat=cumulative" msgstr "synonym för --dirstat=cumulative" -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "synonym för --dirstat=filer,param1,param2..." +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "synonym för --dirstat=filer,<param1>,<param2>..." msgid "warn if changes introduce conflict markers or whitespace errors" msgstr "varna om ändringar introducerar konfliktmarkörer eller blankstegsfel" @@ -15580,7 +15734,7 @@ msgstr "skapa en binärdiff som kan appliceras" msgid "show full pre- and post-image object names on the \"index\" lines" msgstr "" -"visa fullständiga objektnamn i \"index\"-rader för läget bÃ¥de före och efter" +"visa fullständiga objektnamn i â€indexâ€-rader för läget bÃ¥de före och efter" msgid "show colored diff" msgstr "visa färgad diff" @@ -15592,8 +15746,8 @@ msgid "" "highlight whitespace errors in the 'context', 'old' or 'new' lines in the " "diff" msgstr "" -"ljusmarkera blankstegsfel i \"context\" (sammanhang), \"old\" (gamla) eller " -"\"new\" (nya) rader i diffen" +"ljusmarkera blankstegsfel i â€context†(sammanhang), â€old†(gamla) eller " +"â€new†(nya) rader i diffen" msgid "" "do not munge pathnames and use NULs as output field terminators in --raw or " @@ -15606,10 +15760,10 @@ msgid "<prefix>" msgstr "<prefix>" msgid "show the given source prefix instead of \"a/\"" -msgstr "visa givet källprefix istället för \"a/\"" +msgstr "visa givet källprefix istället för â€a/â€" msgid "show the given destination prefix instead of \"b/\"" -msgstr "visa givet mÃ¥lprefix istället för \"b/\"" +msgstr "visa givet mÃ¥lprefix istället för â€b/â€" msgid "prepend an additional prefix to every line of output" msgstr "lägg till ytterligare prefix pÃ¥ alla rader i utdata" @@ -15627,13 +15781,13 @@ msgid "<char>" msgstr "<tecken>" msgid "specify the character to indicate a new line instead of '+'" -msgstr "ange tecken för att ange ny rad istället för \"+\"" +msgstr "ange tecken för att ange ny rad istället för â€+â€" msgid "specify the character to indicate an old line instead of '-'" -msgstr "ange tecken för att ange gammal rad istället för \"-\"" +msgstr "ange tecken för att ange gammal rad istället för â€-â€" msgid "specify the character to indicate a context instead of ' '" -msgstr "ange tecken för att ange sammanhang istället för \" \"" +msgstr "ange tecken för att ange sammanhang istället för †â€" msgid "Diff rename options" msgstr "Diff-namnbytesflaggor" @@ -15703,22 +15857,16 @@ msgid "heuristic to shift diff hunk boundaries for easy reading" msgstr "heuristik för att flytta diff-gränser för lättare läsning" msgid "generate diff using the \"patience diff\" algorithm" -msgstr "skapa diffar med algoritmen \"patience diff\"" +msgstr "skapa diffar med algoritmen â€patience diffâ€" msgid "generate diff using the \"histogram diff\" algorithm" -msgstr "skapa diffar med algoritmen \"histogram diff\"" - -msgid "<algorithm>" -msgstr "<algoritm>" - -msgid "choose a diff algorithm" -msgstr "välj en diff-algoritm" +msgstr "skapa diffar med algoritmen â€histogram diffâ€" msgid "<text>" msgstr "<text>" msgid "generate diff using the \"anchored diff\" algorithm" -msgstr "skapa diffar med algoritmen \"anchored diff\"" +msgstr "skapa diffar med algoritmen â€anchored diffâ€" msgid "<mode>" msgstr "<läge>" @@ -15777,10 +15925,10 @@ msgid "specify how differences in submodules are shown" msgstr "ange hur ändringar i undermoduler visas" msgid "hide 'git add -N' entries from the index" -msgstr "dölj \"git add -N\"-poster frÃ¥n indexet" +msgstr "dölj â€git add -Nâ€-poster frÃ¥n indexet" msgid "treat 'git add -N' entries as real in the index" -msgstr "tolka \"git add -N\"-poster som äkta i indexet" +msgstr "tolka â€git add -Nâ€-poster som äkta i indexet" msgid "<string>" msgstr "<sträng>" @@ -15850,18 +15998,18 @@ msgstr "" #, c-format msgid "failed to read orderfile '%s'" -msgstr "kunde inte läsa orderfilen \"%s\"" +msgstr "kunde inte läsa orderfilen â€%sâ€" msgid "Performing inexact rename detection" msgstr "Utför onöjaktig namnbytesdetektering" #, c-format msgid "No such path '%s' in the diff" -msgstr "Sökvägen \"%s\" finns inte i diffen" +msgstr "Sökvägen â€%s†finns inte i diffen" #, c-format msgid "pathspec '%s' did not match any file(s) known to git" -msgstr "sökvägsangivelsen \"%s\" motsvarade inte nÃ¥gra av git kända filer" +msgstr "sökvägsangivelsen â€%s†motsvarade inte nÃ¥gra av git kända filer" #, c-format msgid "unrecognized pattern: '%s'" @@ -15874,7 +16022,7 @@ msgstr "okänt negativt mönster: %s" #, c-format msgid "your sparse-checkout file may have issues: pattern '%s' is repeated" msgstr "" -"din \"sparse-checkout\"-fil kan ha problem: mönstret \"%s\" förekommer flera " +"din â€sparse-checkoutâ€-fil kan ha problem: mönstret â€%s†förekommer flera " "gÃ¥nger" msgid "disabling cone pattern matching" @@ -15907,7 +16055,7 @@ msgstr "kunde inte skapa kataloger för %s" #, c-format msgid "could not migrate git directory from '%s' to '%s'" -msgstr "kunde inte migrera git-katalog frÃ¥n \"%s\" till \"%s\"" +msgstr "kunde inte migrera git-katalog frÃ¥n â€%s†till â€%sâ€" #, c-format msgid "hint: Waiting for your editor to close the file...%c" @@ -15915,22 +16063,22 @@ msgstr "tips: Väntar pÃ¥ att textredigeringsprogrammet ska stänga filen...%c" #, c-format msgid "could not write to '%s'" -msgstr "kunde inte skriva till \"%s\"" +msgstr "kunde inte skriva till â€%sâ€" #, c-format msgid "could not edit '%s'" -msgstr "kunde inte redigera \"%s\"" +msgstr "kunde inte redigera â€%sâ€" msgid "Filtering content" msgstr "Filtrerar innehÃ¥ll" #, c-format msgid "could not stat file '%s'" -msgstr "kunde inte ta status pÃ¥ filen \"%s\"" +msgstr "kunde inte ta status pÃ¥ filen â€%sâ€" #, c-format msgid "bad git namespace path \"%s\"" -msgstr "felaktig git-namnrymdssökväg \"%s\"" +msgstr "felaktig git-namnrymdssökväg â€%sâ€" #, c-format msgid "too many args to run %s" @@ -15947,7 +16095,7 @@ msgstr "git fetch-pack: förväntade ACK/NAK, fick flush-paket" #, c-format msgid "git fetch-pack: expected ACK/NAK, got '%s'" -msgstr "git fetch-pack: förväntade ACK/NAK, fick \"%s\"" +msgstr "git fetch-pack: förväntade ACK/NAK, fick â€%sâ€" msgid "unable to write to remote" msgstr "kunde inte skriva till fjärren" @@ -15957,11 +16105,11 @@ msgstr "Servern stöder filter" #, c-format msgid "invalid shallow line: %s" -msgstr "ogiltig \"shallow\"-rad: %s" +msgstr "ogiltig â€shallowâ€-rad: %s" #, c-format msgid "invalid unshallow line: %s" -msgstr "ogiltig \"unshallow\"-rad: %s" +msgstr "ogiltig â€unshallowâ€-rad: %s" #, c-format msgid "object not found: %s" @@ -15973,7 +16121,7 @@ msgstr "fel i objekt: %s" #, c-format msgid "no shallow found: %s" -msgstr "ingen \"shallow\" hittades: %s" +msgstr "ingen â€shallow†hittades: %s" #, c-format msgid "expected shallow/unshallow, got %s" @@ -16060,7 +16208,7 @@ msgstr "omaka algoritmer: klient %s; server %s" #, c-format msgid "the server does not support algorithm '%s'" -msgstr "servern stöder inte algoritmen \"%s\"" +msgstr "servern stöder inte algoritmen â€%sâ€" msgid "Server does not support shallow requests" msgstr "Servern stöder inte grunda förfrÃ¥gningar" @@ -16070,15 +16218,15 @@ msgstr "kunde inte skriva anrop till fjärren" #, c-format msgid "expected '%s', received '%s'" -msgstr "förväntade \"%s\", tog emot \"%s\"" +msgstr "förväntade â€%sâ€, tog emot â€%sâ€" #, c-format msgid "expected '%s'" -msgstr "förväntade \"%s\"" +msgstr "förväntade â€%sâ€" #, c-format msgid "unexpected acknowledgment line: '%s'" -msgstr "oväntad bekräftelserad: \"%s\"" +msgstr "oväntad bekräftelserad: â€%sâ€" #, c-format msgid "error processing acks: %d" @@ -16089,19 +16237,18 @@ msgstr "fel vid hantering av bekräftelser: %d" #. #, c-format msgid "expected packfile to be sent after '%s'" -msgstr "väntade att paketfil skulle sändas efter \"%s\"" +msgstr "väntade att paketfil skulle sändas efter â€%sâ€" #. TRANSLATORS: The parameter will be 'ready', a protocol #. keyword. #. #, c-format msgid "expected no other sections to be sent after no '%s'" -msgstr "" -"väntade inte att nÃ¥gra ytterligare sektioner skulle sändas efter \"%s\"" +msgstr "väntade inte att nÃ¥gra ytterligare sektioner skulle sändas efter â€%sâ€" #, c-format msgid "error processing shallow info: %d" -msgstr "fel vid hantering av grund (\"shallow\") info: %d" +msgstr "fel vid hantering av grund (â€shallowâ€) info: %d" #, c-format msgid "expected wanted-ref, got '%s'" @@ -16109,7 +16256,7 @@ msgstr "förväntade wanted-ref, fick %s" #, c-format msgid "unexpected wanted-ref: '%s'" -msgstr "oväntad wanted-ref: \"%s\"" +msgstr "oväntad wanted-ref: â€%sâ€" #, c-format msgid "error processing wanted refs: %d" @@ -16122,7 +16269,7 @@ msgid "no matching remote head" msgstr "inget motsvarande fjärrhuvud" msgid "unexpected 'ready' from remote" -msgstr "oväntat \"ready\" frÃ¥n fjärr" +msgstr "oväntat â€ready†frÃ¥n fjärr" #, c-format msgid "no such remote ref %s" @@ -16134,42 +16281,42 @@ msgstr "Servern tillÃ¥ter inte förfrÃ¥gan om ej tillkännagivet objekt %s" #, c-format msgid "fsmonitor_ipc__send_query: invalid path '%s'" -msgstr "fsmonitor_ipc__send_query: ogilitg sökväg \"%s\"" +msgstr "fsmonitor_ipc__send_query: ogilitg sökväg â€%sâ€" #, c-format msgid "fsmonitor_ipc__send_query: unspecified error on '%s'" -msgstr "fsmonitor_ipc__send_query: ospecificerat fel pÃ¥ \"%s\"" +msgstr "fsmonitor_ipc__send_query: ospecificerat fel pÃ¥ â€%sâ€" msgid "fsmonitor--daemon is not running" msgstr "fsmonitor--daemon kör inte" #, c-format msgid "could not send '%s' command to fsmonitor--daemon" -msgstr "kunde inte sända kommandot \"%s\" till fsmonitor--daemon" +msgstr "kunde inte sända kommandot â€%s†till fsmonitor--daemon" #, c-format msgid "bare repository '%s' is incompatible with fsmonitor" -msgstr "naket arkiv \"%s\" är inkompatibelt med fsmonitor" +msgstr "naket arkiv â€%s†är inkompatibelt med fsmonitor" #, c-format msgid "repository '%s' is incompatible with fsmonitor due to errors" -msgstr "arkivet \"%s\" är inkompatibelt med fsmonitor pÃ¥ grund av fel" +msgstr "arkivet â€%s†är inkompatibelt med fsmonitor pÃ¥ grund av fel" #, c-format msgid "remote repository '%s' is incompatible with fsmonitor" -msgstr "fjärrarkivet \"%s\" är inkompatibelt med fsmonitor" +msgstr "fjärrarkivet â€%s†är inkompatibelt med fsmonitor" #, c-format msgid "virtual repository '%s' is incompatible with fsmonitor" -msgstr "det virtuella arkivet \"%s\" är inkompatibelt med fsmonitor" +msgstr "det virtuella arkivet â€%s†är inkompatibelt med fsmonitor" #, c-format msgid "" "socket directory '%s' is incompatible with fsmonitor due to lack of Unix " "sockets support" msgstr "" -"uttagskatalogen \"%s\" är inkompatibelt med fsmonitor pÃ¥ grund av avsaknad " -"av Unix-uttag" +"uttagskatalogen â€%s†är inkompatibelt med fsmonitor pÃ¥ grund av avsaknad av " +"Unix-uttag" msgid "" "git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n" @@ -16193,18 +16340,18 @@ msgid "" "to read about a specific subcommand or concept.\n" "See 'git help git' for an overview of the system." msgstr "" -"\"git help -a\" och \"git help -g\" visar tillgängliga underkommandon och\n" -"nÃ¥gra konceptvägledningar. Se \"git help <kommando>\" eller \"git help\n" -"<koncept>\" för att läsa mer om specifika underkommandon och koncept.\n" -"See \"git help git\" för en översikt över systemet." +"â€git help -a†och â€git help -g†visar tillgängliga underkommandon och\n" +"nÃ¥gra konceptvägledningar. Se â€git help <kommando>†eller â€git help\n" +"<koncept>†för att läsa mer om specifika underkommandon och koncept.\n" +"See â€git help git†för en översikt över systemet." #, c-format msgid "unsupported command listing type '%s'" -msgstr "okänd kommandolisttyp \"%s\"" +msgstr "okänd kommandolisttyp â€%sâ€" #, c-format msgid "no directory given for '%s' option\n" -msgstr "ingen katalog angavs för flaggan \"%s\"\n" +msgstr "ingen katalog angavs för flaggan â€%sâ€\n" #, c-format msgid "no namespace given for --namespace\n" @@ -16228,15 +16375,15 @@ msgstr "okänd flagga: %s\n" #, c-format msgid "while expanding alias '%s': '%s'" -msgstr "vid expandering av aliaset \"%s\": \"%s\"" +msgstr "vid expandering av aliaset â€%sâ€: â€%sâ€" #, c-format msgid "" "alias '%s' changes environment variables.\n" "You can use '!git' in the alias to do this" msgstr "" -"aliaset \"%s\" ändrar miljövariabler.\n" -"Du kan använda \"!git\" i aliaset för att göra det" +"aliaset â€%s†ändrar miljövariabler.\n" +"Du kan använda â€!git†i aliaset för att göra det" #, c-format msgid "empty alias for %s" @@ -16257,7 +16404,7 @@ msgstr "stäng misslyckades pÃ¥ standard ut" #, c-format msgid "alias loop detected: expansion of '%s' does not terminate:%s" -msgstr "alias-slinga detekterades: expansionen av \"%s\" avslutas aldrig:%s" +msgstr "alias-slinga detekterades: expansionen av â€%s†avslutas aldrig:%s" #, c-format msgid "cannot handle %s as a builtin" @@ -16274,18 +16421,18 @@ msgstr "" #, c-format msgid "expansion of alias '%s' failed; '%s' is not a git command\n" msgstr "" -"expandering av alias \"%s\" misslyckades; \"%s\" är inte ett git-kommando\n" +"expandering av alias â€%s†misslyckades; â€%s†är inte ett git-kommando\n" #, c-format msgid "failed to run command '%s': %s\n" -msgstr "misslyckades köra kommandot \"%s\": %s\n" +msgstr "misslyckades köra kommandot â€%sâ€: %s\n" msgid "could not create temporary file" msgstr "kunde inte skapa temporära fil" #, c-format msgid "failed writing detached signature to '%s'" -msgstr "misslyckades skriva fristÃ¥ende signatur till \"%s\"" +msgstr "misslyckades skriva fristÃ¥ende signatur till â€%sâ€" msgid "" "gpg.ssh.allowedSignersFile needs to be configured and exist for ssh " @@ -16298,7 +16445,7 @@ msgid "" "ssh-keygen -Y find-principals/verify is needed for ssh signature " "verification (available in openssh version 8.2p1+)" msgstr "" -"\"ssh-keygen -Y find-principals/verify\" behövs för att bekräfta ssh-" +"â€ssh-keygen -Y find-principals/verify†behövs för att bekräfta ssh-" "signaturer (tillgängligt i openssh version 8.2p1+)" #, c-format @@ -16307,11 +16454,11 @@ msgstr "Ã¥terkallningsfilen för ssh-signering inställd men saknas: %s" #, c-format msgid "bad/incompatible signature '%s'" -msgstr "felaktig/inkompatibel signatur \"%s\"" +msgstr "felaktig/inkompatibel signatur â€%sâ€" #, c-format msgid "failed to get the ssh fingerprint for key '%s'" -msgstr "misslyckades hämta ssh-fingeravtrycket för nyckeln \"%s\"" +msgstr "misslyckades hämta ssh-fingeravtrycket för nyckeln â€%sâ€" msgid "" "either user.signingkey or gpg.ssh.defaultKeyCommand needs to be configured" @@ -16339,26 +16486,26 @@ msgstr "user.signingKey mÃ¥ste anges för ssh-signering" #, c-format msgid "failed writing ssh signing key to '%s'" -msgstr "misslyckades skriva ssh-signeringsnyckel till \"%s\"" +msgstr "misslyckades skriva ssh-signeringsnyckel till â€%sâ€" #, c-format msgid "failed writing ssh signing key buffer to '%s'" -msgstr "misslyckades skriva ssh-signeringsnyckelbuffert till \"%s\"" +msgstr "misslyckades skriva ssh-signeringsnyckelbuffert till â€%sâ€" msgid "" "ssh-keygen -Y sign is needed for ssh signing (available in openssh version " "8.2p1+)" msgstr "" -"\"ssh-keygen -Y sign\" behövs för ssh-signering (tillgängligt i openssh " +"â€ssh-keygen -Y sign†behövs för ssh-signering (tillgängligt i openssh " "version 8.2p1+)" #, c-format msgid "failed reading ssh signing data buffer from '%s'" -msgstr "misslyckades läsa ssh-signeringsdatabuffert frÃ¥n \"%s\"" +msgstr "misslyckades läsa ssh-signeringsdatabuffert frÃ¥n â€%sâ€" #, c-format msgid "ignored invalid color '%.*s' in log.graphColors" -msgstr "ignorerade felaktig färg \"%.*s\" i log.graphColors" +msgstr "ignorerade felaktig färg â€%.*s†i log.graphColors" msgid "" "given pattern contains NULL byte (via -f <file>). This is only supported " @@ -16369,11 +16516,11 @@ msgstr "" #, c-format msgid "'%s': unable to read %s" -msgstr "\"%s\" kunde inte läsa %s" +msgstr "â€%s†kunde inte läsa %s" #, c-format msgid "'%s': short read" -msgstr "\"%s\": kort läsning" +msgstr "â€%sâ€: kort läsning" msgid "start a working area (see also: git help tutorial)" msgstr "starta arbetskatalog (se ocksÃ¥: git help tutorial)" @@ -16422,7 +16569,7 @@ msgstr "Filformat, protokoll och andra gränssnitt tänkta för utvecklare" #, c-format msgid "available git commands in '%s'" -msgstr "git-kommandon tillgängliga i \"%s\"" +msgstr "git-kommandon tillgängliga i â€%sâ€" msgid "git commands available from elsewhere on your $PATH" msgstr "git-kommandon frÃ¥n andra platser i din $PATH" @@ -16446,39 +16593,39 @@ msgid "Command aliases" msgstr "Kommadoalias" msgid "See 'git help <command>' to read about a specific subcommand" -msgstr "Se \"git help <kommando>\" för att läsa om ett specifikt underkommando" +msgstr "Se â€git help <kommando>†för att läsa om ett specifikt underkommando" #, 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 "" -"\"%s\" verkar vara ett git-kommando, men vi kan inte\n" +"â€%s†verkar vara ett git-kommando, men vi kan inte\n" "köra det. Kanske git-%s är trasigt?" #, c-format msgid "git: '%s' is not a git command. See 'git --help'." -msgstr "git: \"%s\" är inte ett git-kommando. Se \"git --help\"." +msgstr "git: â€%s†är inte ett git-kommando. Se â€git --helpâ€." msgid "Uh oh. Your system reports no Git commands at all." msgstr "Oj dÃ¥. Ditt system rapporterar inga Git-kommandon alls." #, c-format msgid "WARNING: You called a Git command named '%s', which does not exist." -msgstr "VARNING: Du anropade ett Git-kommando vid namn \"%s\", som inte finns." +msgstr "VARNING: Du anropade ett Git-kommando vid namn â€%sâ€, som inte finns." #, c-format msgid "Continuing under the assumption that you meant '%s'." -msgstr "Fortsätter under förutsättningen att du menade \"%s\"." +msgstr "Fortsätter under förutsättningen att du menade â€%sâ€." #, c-format msgid "Run '%s' instead [y/N]? " -msgstr "Köra \"%s\" istället (j/N)?" +msgstr "Köra â€%s†istället (j/N)?" #, c-format msgid "Continuing in %0.1f seconds, assuming that you meant '%s'." msgstr "" -"Fortsätter om %0.1f sekunder, under förutsättningen att du menade \"%s\"." +"Fortsätter om %0.1f sekunder, under förutsättningen att du menade â€%sâ€." msgid "" "\n" @@ -16518,8 +16665,8 @@ 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 "" -"Kroken \"%s\" ignorerades eftersom den inte är markerad som körbar.\n" -"Du kan inaktivera varningen med \"git config advice.ignoredHook false\"." +"Kroken â€%s†ignorerades eftersom den inte är markerad som körbar.\n" +"Du kan inaktivera varningen med â€git config advice.ignoredHook falseâ€." #, c-format msgid "argument to --packfile must be a valid hash (got '%s')" @@ -16544,15 +16691,15 @@ msgstr "CURLSSLOPT_NO_REVOKE stöds inte av cURL < 7.44.0" #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" -msgstr "SSL-bakändan \"%s\" stöds inte. Dessa SSL-bakändor stöds:" +msgstr "SSL-bakändan â€%s†stöds inte. Dessa SSL-bakändor stöds:" #, c-format msgid "Could not set SSL backend to '%s': cURL was built without SSL backends" -msgstr "Kan inte sätta SSL-bakända till \"%s\": cURL byggdes utan SSL-bakändor" +msgstr "Kan inte sätta SSL-bakända till â€%sâ€: cURL byggdes utan SSL-bakändor" #, c-format msgid "Could not set SSL backend to '%s': already set" -msgstr "Kunde inte sätta SSL-bakända till \"%s\": redan valt" +msgstr "Kunde inte sätta SSL-bakända till â€%sâ€: redan valt" #, c-format msgid "" @@ -16600,14 +16747,14 @@ msgstr "ingen e-post angavs och autodetektering är inaktiverad" #, c-format msgid "unable to auto-detect email address (got '%s')" -msgstr "kunde inte autodetektera e-postadress (fick \"%s\")" +msgstr "kunde inte autodetektera e-postadress (fick â€%sâ€)" msgid "no name was given and auto-detection is disabled" msgstr "inget namn angavs och autodetektering är inaktiverad" #, c-format msgid "unable to auto-detect name (got '%s')" -msgstr "kunde inte autodetektera namn (fick \"%s\")" +msgstr "kunde inte autodetektera namn (fick â€%sâ€)" #, c-format msgid "empty ident name (for <%s>) not allowed" @@ -16618,22 +16765,22 @@ msgid "name consists only of disallowed characters: %s" msgstr "namnet bestÃ¥r enbart av ej tillÃ¥tna tecken: %s" msgid "expected 'tree:<depth>'" -msgstr "förväntade \"tree:<djup>\"" +msgstr "förväntade â€tree:<djup>â€" msgid "sparse:path filters support has been dropped" msgstr "sparse:sökväg-filter stöds inte längre" #, c-format msgid "'%s' for 'object:type=<type>' is not a valid object type" -msgstr "\"%s\" för \"object:type=<typ>\" är inte en giltig objekttyp" +msgstr "â€%s†för â€object:type=<typ>†är inte en giltig objekttyp" #, c-format msgid "invalid filter-spec '%s'" -msgstr "felaktig filterspecifikation: \"%s\"" +msgstr "felaktig filterspecifikation: â€%sâ€" #, c-format msgid "must escape char in sub-filter-spec: '%c'" -msgstr "mÃ¥ste använda specialsekvens i delfilter-spec: \"%c\"" +msgstr "mÃ¥ste använda specialsekvens i delfilter-spec: â€%câ€" msgid "expected something after combine:" msgstr "förväntade nÃ¥gonting efter combine:" @@ -16652,7 +16799,7 @@ msgstr "objektfiltrering" #, c-format msgid "unable to access sparse blob in '%s'" -msgstr "kunde inte nÃ¥ gles blob pÃ¥ \"%s\"" +msgstr "kunde inte nÃ¥ gles blob pÃ¥ â€%sâ€" #, c-format msgid "unable to parse sparse filter data in %s" @@ -16660,11 +16807,11 @@ msgstr "kunde inte tolka gles filterdata i %s" #, c-format msgid "entry '%s' in tree %s has tree mode, but is not a tree" -msgstr "posten \"%s\" i trädet %s har träd-läge, men är inte ett träd" +msgstr "posten â€%s†i trädet %s har träd-läge, men är inte ett träd" #, c-format msgid "entry '%s' in tree %s has blob mode, but is not a blob" -msgstr "posten \"%s\" i trädet %s har blob-läge, men är inte en blob" +msgstr "posten â€%s†i trädet %s har blob-läge, men är inte en blob" #, c-format msgid "unable to load root tree for commit %s" @@ -16680,10 +16827,10 @@ msgid "" "may have crashed in this repository earlier:\n" "remove the file manually to continue." msgstr "" -"Kunde inte skapa \"%s.lock\": %s.\n" +"Kunde inte skapa â€%s.lockâ€: %s.\n" "\n" "Det verkar som en annan git-process kör i det här arkivet, t.ex.\n" -"ett textredigeringsprogram startat av \"git commit\". Se till att\n" +"ett textredigeringsprogram startat av â€git commitâ€. Se till att\n" "alla processer avslutats och försök sedan igen. Om det fortfarande\n" "misslyckas kanske en git-process har kraschat i det här arkivet\n" "tidigare:\n" @@ -16691,14 +16838,14 @@ msgstr "" #, c-format msgid "Unable to create '%s.lock': %s" -msgstr "Kunde inte skapa \"%s.lock\": %s" +msgstr "Kunde inte skapa â€%s.lockâ€: %s" #, c-format msgid "unexpected line: '%s'" -msgstr "oväntad rad: \"%s\"" +msgstr "oväntad rad: â€%sâ€" msgid "expected flush after ls-refs arguments" -msgstr "förväntade \"flush\" efter ls-refs-argument" +msgstr "förväntade â€flush†efter ls-refs-argument" msgid "quoted CRLF detected" msgstr "citerad CRLF upptäcktes" @@ -16743,12 +16890,12 @@ msgstr "" "finns:\n" "%s" -msgid "Failed to execute internal merge" -msgstr "Misslyckades exekvera intern sammanslagning" +msgid "failed to execute internal merge" +msgstr "misslyckades exekvera intern sammanslagning" #, c-format -msgid "Unable to add %s to database" -msgstr "Kunde inte lägga till %s till databasen" +msgid "unable to add %s to database" +msgstr "kunde inte lägga till %s till databasen" #, c-format msgid "Auto-merging %s" @@ -16785,7 +16932,7 @@ msgid "" "WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was " "renamed." msgstr "" -"VARNING: Undviker att applicera namnändring %s -> %s pÃ¥ %s, dÃ¥ %s själv har " +"VARNING: Undviker att applicera namnändring %s → %s pÃ¥ %s, dÃ¥ %s själv har " "bytt namn." #, c-format @@ -16831,7 +16978,7 @@ msgid "" "conflicts AND collides with another path; this may result in nested conflict " "markers." msgstr "" -"KONFLIKT (namnbyte involverad i krock): namnbyte av %s -> %s har " +"KONFLIKT (namnbyte involverad i krock): namnbyte av %s → %s har " "innehÃ¥llskonflikter OCH krockar med en annan sökväg; detta kan leda till " "nästlade konfliktmarkörer." @@ -16946,17 +17093,17 @@ msgstr "(felaktig incheckning)\n" #, c-format msgid "add_cacheinfo failed for path '%s'; merge aborting." msgstr "" -"add_cacheinfo misslyckades för sökvägen \"%s\"; avslutar sammanslagningen." +"add_cacheinfo misslyckades för sökvägen â€%sâ€; avslutar sammanslagningen." #, c-format msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." msgstr "" -"add_cacheinfo misslyckades uppdatera för sökvägen \"%s\"; avslutar " +"add_cacheinfo misslyckades uppdatera för sökvägen â€%sâ€; avslutar " "sammanslagningen." #, c-format msgid "failed to create path '%s'%s" -msgstr "misslyckades skapa sökvägen \"%s\"%s" +msgstr "misslyckades skapa sökvägen â€%sâ€%s" #, c-format msgid "Removing %s to make room for subdirectory\n" @@ -16967,23 +17114,23 @@ msgstr ": kanske en K/F-konflikt?" #, c-format msgid "refusing to lose untracked file at '%s'" -msgstr "vägrar förlora ospÃ¥rad fil vid \"%s\"" +msgstr "vägrar förlora ospÃ¥rad fil vid â€%sâ€" #, c-format msgid "blob expected for %s '%s'" -msgstr "blob förväntades för %s \"%s\"" +msgstr "blob förväntades för %s â€%sâ€" #, c-format msgid "failed to open '%s': %s" -msgstr "misslyckades öppna \"%s\": %s" +msgstr "misslyckades öppna â€%sâ€: %s" #, c-format msgid "failed to symlink '%s': %s" -msgstr "misslyckades skapa symboliska länken \"%s\": %s" +msgstr "misslyckades skapa symboliska länken â€%sâ€: %s" #, c-format msgid "do not know what to do with %06o %s '%s'" -msgstr "vet inte hur %06o %s \"%s\" ska hanteras" +msgstr "vet inte hur %06o %s â€%s†ska hanteras" #, c-format msgid "Fast-forwarding submodule %s to the following commit:" @@ -17071,7 +17218,7 @@ msgstr "namnbytt" #, c-format msgid "Refusing to lose dirty file at %s" -msgstr "Vägrar förlora lortig fil vid \"%s\"" +msgstr "Vägrar förlora lortig fil vid â€%sâ€" #, c-format msgid "Refusing to lose untracked file at %s, even though it's in the way." @@ -17079,7 +17226,7 @@ msgstr "Vägrar förlora ospÃ¥rad fil vid %s, trots att den är i vägen." #, c-format msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" -msgstr "KONFLIKT (namnbyte/tillägg): Namnbyte %s->%s i %s. Lade till %s i %s" +msgstr "KONFLIKT (namnbyte/tillägg): Namnbyte %s→%s i %s. Lade till %s i %s" #, c-format msgid "%s is a directory in %s adding as %s instead" @@ -17091,19 +17238,18 @@ msgstr "Vägrar förlora ospÃ¥rad fil vid %s; lägger till som %s istället" #, c-format msgid "" -"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s" -"\"->\"%s\" in \"%s\"%s" +"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename " +"\"%s\"->\"%s\" in \"%s\"%s" msgstr "" -"KONFLIKT (namnbyte/namnbyte): Namnbyte \"%s\"->\"%s\" pÃ¥ grenen \"%s\" " -"namnbyte \"%s\"->\"%s\" i \"%s\"%s" +"KONFLIKT (namnbyte/namnbyte): Namnbyte â€%sâ€â†’â€%s†pÃ¥ grenen â€%s†namnbyte " +"â€%sâ€â†’â€%s†i â€%sâ€%s" msgid " (left unresolved)" msgstr " (lämnad olöst)" #, c-format msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" -msgstr "" -"KONFLIKT (namnbyte/namnbyte): Namnbyte %s->%s i %s. Namnbyte %s->%s i %s" +msgstr "KONFLIKT (namnbyte/namnbyte): Namnbyte %s→%s i %s. Namnbyte %s→%s i %s" #, c-format msgid "" @@ -17120,8 +17266,8 @@ msgid "" "CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-" ">%s in %s" msgstr "" -"KONFLIKT (namnbyte/namnbyte): Namnbytt katalog %s->%s i %s. Namnbytt katalog " -"%s->%s i %s" +"KONFLIKT (namnbyte/namnbyte): Namnbytt katalog %s→%s i %s. Namnbytt katalog " +"%s→%s i %s" msgid "modify" msgstr "ändra" @@ -17178,13 +17324,25 @@ msgstr "sammanslagningen returnerade ingen incheckning" #, c-format msgid "Could not parse object '%s'" -msgstr "Kunde inte tolka objektet \"%s\"" +msgstr "Kunde inte tolka objektet â€%sâ€" msgid "failed to read the cache" msgstr "misslyckades läsa cachen" msgid "multi-pack-index OID fanout is of the wrong size" -msgstr "multi-pack-indexets OID-utbredning har fel storlek" +msgstr "OID-utbredning för multi-pack-index har fel storlek" + +#, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"oid-utbredning i fel ordning: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" + +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "OID-uppslagningsstycket för multi-pack-index har fel storlek" + +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "objekt-offset-stycket för multi-pack-index har fel storlek" #, c-format msgid "multi-pack-index file %s is too small" @@ -17202,36 +17360,54 @@ msgstr "multi-pack-indexversionen %d stöds inte" msgid "multi-pack-index hash version %u does not match version %u" msgstr "multi-pack-index-hashversionen %u stämmer inte med versionen %u" -msgid "multi-pack-index missing required pack-name chunk" -msgstr "multi-pack-index saknar krävd paketnamn-stycke" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "" +"nödvändigt paketnamn-stycke för multi-pack-index saknas eller är trasigt" + +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "" +"nödvändigt OID-utbredningsstycke för multi-pack-index saknas eller är trasigt" -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "multi-pack-index saknar krävt OID-utbredningsstycke" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "" +"nödvändigt OID-uppslagningsstycke för multi-pack-index saknas eller är " +"trasigt" -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "multi-pack-index saknar krävt OID-uppslagnignsstycke" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "" +"nödvändigt objekt-offsetstycke för multi-pack-index saknas eller är trasigt" -msgid "multi-pack-index missing required object offsets chunk" -msgstr "multi-pack-index saknar krävt objekt-offsetstycke" +msgid "multi-pack-index pack-name chunk is too short" +msgstr "paketnamnstycke för multi-pack-index är för kort" #, c-format msgid "multi-pack-index pack names out of order: '%s' before '%s'" -msgstr "multi-pack-index-paketnamn i fel ordning: \"%s\" före \"%s\"" +msgstr "paketnamn för multi-pack-index i fel ordning: â€%s†före â€%sâ€" #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "bad pack-int-id: %u (%u paket totalt)" +msgid "MIDX does not contain the BTMP chunk" +msgstr "MIDX innehÃ¥ller inte BTMP-stycket" + +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "kunde inte läsa det bitmappade paketet %<PRIu32>" + msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" -msgstr "multi-pack-index skriver 64-bitars offset, men off_t är för liten" +msgstr "multi-pack-index innehÃ¥ller 64-bitars offset, men off_t är för liten" + +msgid "multi-pack-index large offset out of bounds" +msgstr "stort offset för mult-pack-index utanför gränsen" #, c-format msgid "failed to add packfile '%s'" -msgstr "misslyckades läsa paketfilen \"%s\"" +msgstr "misslyckades läsa paketfilen â€%sâ€" #, c-format msgid "failed to open pack-index '%s'" -msgstr "misslyckades öppna paketindexet \"%s\"" +msgstr "misslyckades öppna paketindexet â€%sâ€" #, c-format msgid "failed to locate object %d in packfile" @@ -17275,7 +17451,7 @@ msgstr "sÃ¥g inte paketfilen %s som skulle kastas" #, c-format msgid "preferred pack '%s' is expired" -msgstr "föredraget paket \"%s\" har löpt ut" +msgstr "föredraget paket â€%s†har löpt ut" msgid "no pack files to index." msgstr "inga paketfiler att indexera." @@ -17302,12 +17478,6 @@ msgstr "felaktig kontrollsumma" msgid "Looking for referenced packfiles" msgstr "Ser efter refererade packfiler" -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "" -"oid-utbredning i fel ordning: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" - msgid "the midx contains no oid" msgstr "midx saknar oid" @@ -17367,9 +17537,9 @@ msgid "" "commit/abort the previous merge before you start a new notes merge." msgstr "" "Du har inte avslutat föregÃ¥ende antecknings-sammanslagning (%s finns).\n" -"Använd \"git notes merge --commit\" eller \"git notes merge --abort\" för " -"att checka in eller avbryta föregÃ¥ende sammanslagning innan du pÃ¥börjar en " -"ny antecknings-sammanslagning." +"Använd â€git notes merge --commit†eller â€git notes merge --abort†för att " +"checka in eller avbryta föregÃ¥ende sammanslagning innan du pÃ¥börjar en ny " +"antecknings-sammanslagning." #, c-format msgid "You have not concluded your notes merge (%s exists)." @@ -17392,7 +17562,7 @@ msgstr "Vägrar skriva över anteckningar i %s (utanför refs/notes/)" #. #, c-format msgid "Bad %s value: '%s'" -msgstr "Felaktigt värde pÃ¥ %s: \"%s\"" +msgstr "Felaktigt värde pÃ¥ %s: â€%sâ€" #, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" @@ -17407,33 +17577,33 @@ msgid "%s: ignoring alternate object stores, nesting too deep" msgstr "%s: ignorerar supplerande objektlager, för djup nästling" msgid "unable to fdopen alternates lockfile" -msgstr "kan inte utföra \"fdopen\" pÃ¥ suppleantlÃ¥sfil" +msgstr "kan inte utföra â€fdopen†pÃ¥ suppleantlÃ¥sfil" msgid "unable to read alternates file" -msgstr "kan inte läsa \"alternates\"-filen" +msgstr "kan inte läsa â€alternatesâ€-filen" msgid "unable to move new alternates file into place" -msgstr "kan inte flytta ny \"alternates\"-fil pÃ¥ plats" +msgstr "kan inte flytta ny â€alternatesâ€-fil pÃ¥ plats" #, c-format msgid "path '%s' does not exist" -msgstr "sökvägen \"%s\" finns inte" +msgstr "sökvägen â€%s†finns inte" #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." -msgstr "referensarkivet \"%s\" som en länkad utcheckning stöds inte ännu." +msgstr "referensarkivet â€%s†som en länkad utcheckning stöds inte ännu." #, c-format msgid "reference repository '%s' is not a local repository." -msgstr "referensarkivet \"%s\" är inte ett lokalt arkiv." +msgstr "referensarkivet â€%s†är inte ett lokalt arkiv." #, c-format msgid "reference repository '%s' is shallow" -msgstr "referensarkivet \"%s\" är grunt" +msgstr "referensarkivet â€%s†är grunt" #, c-format msgid "reference repository '%s' is grafted" -msgstr "referensarkivet \"%s\" är ympat" +msgstr "referensarkivet â€%s†är ympat" #, c-format msgid "could not find object directory matching %s" @@ -17445,7 +17615,7 @@ msgstr "felaktig rad vid tolkning av supplerande referenser: %s" #, c-format msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" -msgstr "försök att utföra \"mmap\" pÃ¥ %<PRIuMAX> över gränsen %<PRIuMAX>" +msgstr "försök att utföra â€mmap†pÃ¥ %<PRIuMAX> över gränsen %<PRIuMAX>" #, c-format msgid "mmap failed%s" @@ -17457,11 +17627,11 @@ msgstr "objektfilen %s är tom" #, c-format msgid "corrupt loose object '%s'" -msgstr "trasigt löst objekt \"%s\"" +msgstr "trasigt löst objekt â€%sâ€" #, c-format msgid "garbage at end of loose object '%s'" -msgstr "skräp i slutet av löst objekt \"%s\"" +msgstr "skräp i slutet av löst objekt â€%sâ€" #, c-format msgid "unable to open loose object %s" @@ -17500,7 +17670,7 @@ msgstr "kunde inte skriva filen %s" #, c-format msgid "unable to set permission to '%s'" -msgstr "kan inte sätta behörigheten till \"%s\"" +msgstr "kan inte sätta behörigheten till â€%sâ€" msgid "error when closing loose object file" msgstr "fel vid stängning av fil för löst objekt" @@ -17518,11 +17688,11 @@ msgstr "kunde inte skriva fil för löst objekt" #, c-format msgid "unable to deflate new object %s (%d)" -msgstr "kan inte utföra \"deflate\" pÃ¥ nytt objekt %s (%d)" +msgstr "kan inte utföra â€deflate†pÃ¥ nytt objekt %s (%d)" #, c-format msgid "deflateEnd on object %s failed (%d)" -msgstr "\"deflateend\" pÃ¥ objektet %s misslyckades (%d)" +msgstr "â€deflateEnd†pÃ¥ objektet %s misslyckades (%d)" #, c-format msgid "confused by unstable object source data for %s" @@ -17534,11 +17704,11 @@ msgstr "skriv strömobjektet %ld != %<PRIuMAX>" #, c-format msgid "unable to stream deflate new object (%d)" -msgstr "kan inte utföra \"deflate\" pÃ¥ nytt strömobjekt (%d)" +msgstr "kan inte utföra â€deflate†pÃ¥ nytt strömobjekt (%d)" #, c-format msgid "deflateEnd on stream object failed (%d)" -msgstr "\"deflateend\" pÃ¥ strömobjektet misslyckades (%d)" +msgstr "â€deflatEend†pÃ¥ strömobjektet misslyckades (%d)" #, c-format msgid "unable to create directory %s" @@ -17573,7 +17743,7 @@ msgstr "%s: filtypen stöds ej" #, c-format msgid "%s is not a valid '%s' object" -msgstr "%s är inte ett giltigt \"%s\"-objekt" +msgstr "%s är inte ett giltigt â€%sâ€-objekt" #, c-format msgid "unable to open %s" @@ -17585,7 +17755,7 @@ msgstr "hash stämmer inte för %s (förväntade %s)" #, c-format msgid "unable to mmap %s" -msgstr "kan inte utföra \"mmap\" för %s" +msgstr "kan inte utföra â€mmap†för %s" #, c-format msgid "unable to unpack header of %s" @@ -17688,72 +17858,72 @@ msgstr "" "\n" " git switch -c $br $(git rev-parse ...)\n" "\n" -"där \"$br\" pÃ¥ nÃ¥got sätt blivit tomt och en 40-hex-referens skapats.\n" +"där â€$br†pÃ¥ nÃ¥got sätt blivit tomt och en 40-hex-referens skapats.\n" "Undersök referenserna och ta kanske bort dem. Stäng av meddelandet\n" -"genom att köra \"git config advice.objectNameWarning false\"" +"genom att köra â€git config advice.objectNameWarning falseâ€" #, c-format msgid "log for '%.*s' only goes back to %s" -msgstr "loggen för \"%.*s\" räcker bara tillbaka till %s" +msgstr "loggen för â€%.*s†räcker bara tillbaka till %s" #, c-format msgid "log for '%.*s' only has %d entries" -msgstr "loggen för \"%.*s\" har bara %d poster" +msgstr "loggen för â€%.*s†har bara %d poster" #, c-format msgid "path '%s' exists on disk, but not in '%.*s'" -msgstr "Sökvägen \"%s\" finns pÃ¥ disken, men inte i \"%.*s\"" +msgstr "Sökvägen â€%s†finns pÃ¥ disken, men inte i â€%.*sâ€" #, c-format msgid "" "path '%s' exists, but not '%s'\n" "hint: Did you mean '%.*s:%s' aka '%.*s:./%s'?" msgstr "" -"sökvägen \"%s\" finns, men inte i \"%s\"\n" -"tips: Menade du \"%.*s:%s\", även känd som \"%.*s:./%s\"?" +"sökvägen â€%s†finns, men inte i â€%sâ€\n" +"tips: Menade du â€%.*s:%sâ€, även känd som â€%.*s:./%sâ€?" #, c-format msgid "path '%s' does not exist in '%.*s'" -msgstr "sökvägen \"%s\" finns inte i \"%.*s\"" +msgstr "sökvägen â€%s†finns inte i â€%.*sâ€" #, c-format msgid "" "path '%s' is in the index, but not at stage %d\n" "hint: Did you mean ':%d:%s'?" msgstr "" -"sökvägen \"%s\" finns i indexet men inte i etapp %d\n" -"tips: Menade du \":%d:%s\"?" +"sökvägen â€%s†finns i indexet men inte i etapp %d\n" +"tips: Menade du â€:%d:%sâ€?" #, c-format msgid "" "path '%s' is in the index, but not '%s'\n" "hint: Did you mean ':%d:%s' aka ':%d:./%s'?" msgstr "" -"sökvägen \"%s\" finns i indexet, men inte i \"%s\"\n" -"tips: Menade du \":%d:%s\", även känd som \":%d:./%s\"?" +"sökvägen â€%s†finns i indexet, men inte i â€%sâ€\n" +"tips: Menade du â€:%d:%sâ€, även känd som â€:%d:./%sâ€?" #, c-format msgid "path '%s' exists on disk, but not in the index" -msgstr "sökvägen \"%s\" finns pÃ¥ disk, men inte i indexet" +msgstr "sökvägen â€%s†finns pÃ¥ disk, men inte i indexet" #, c-format msgid "path '%s' does not exist (neither on disk nor in the index)" -msgstr "sökvägen \"%s\" finns inte (varken i disken eller i indexet)" +msgstr "sökvägen â€%s†finns inte (varken i disken eller i indexet)" msgid "relative path syntax can't be used outside working tree" msgstr "relativ sökväg kan inte användas utanför arbetskatalogen" #, c-format msgid "<object>:<path> required, only <object> '%s' given" -msgstr "<objekt>:<sökväg> krävs, endast <objekt> \"%s\" har angivits" +msgstr "<objekt>:<sökväg> krävs, endast <objekt> â€%s†har angivits" #, c-format msgid "invalid object name '%.*s'." -msgstr "felaktigt objektnamn \"%.*s\"." +msgstr "felaktigt objektnamn â€%.*sâ€." #, c-format msgid "invalid object type \"%s\"" -msgstr "ogiltig objekttyp \"%s\"" +msgstr "ogiltig objekttyp â€%sâ€" #, c-format msgid "object %s is a %s, not a %s" @@ -17785,7 +17955,7 @@ msgstr "trasigt bitkarteindex (felaktigt huvud)" #, c-format msgid "unsupported version '%d' for bitmap index file" -msgstr "versionen \"%d\" i bitkarteindexfilen stöds inte" +msgstr "versionen â€%d†i bitkarteindexfilen stöds inte" msgid "corrupted bitmap index file (too short to fit hash cache)" msgstr "trasigt bitkarteindex (för kort för att fÃ¥ plats för hash-cache)" @@ -17795,7 +17965,7 @@ msgstr "trasigt bitkarteindex (för kort för att fÃ¥ plats för uppslagstabell) #, c-format msgid "duplicate entry in bitmap index: '%s'" -msgstr "duplicerad post i bitkarteindex: \"%s\"" +msgstr "duplicerad post i bitkarteindex: â€%sâ€" #, c-format msgid "corrupt ewah bitmap: truncated header for entry %d" @@ -17812,7 +17982,7 @@ msgid "invalid XOR offset in bitmap pack index" msgstr "ogiltigt XOR-offset i bitkarte-packindex" msgid "cannot fstat bitmap file" -msgstr "kan inte utföra \"fstat\" pÃ¥ bitkartefil" +msgstr "kan inte utföra â€fstat†pÃ¥ bitkartefil" msgid "checksum doesn't match in MIDX and bitmap" msgstr "checksumman stämmer inte i MIDX och bitkarta" @@ -17824,6 +17994,9 @@ msgstr "flerpaketsbitkarta saknar nödvändigt omvänt index" msgid "could not open pack %s" msgstr "kunde inte öppna paketfilen %s" +msgid "could not determine MIDX preferred pack" +msgstr "kunde inte bestämma det föredragna MIDX-paketet" + #, c-format msgid "preferred pack (%s) is invalid" msgstr "föredragen paketfil (%s) är ogiltig" @@ -17841,20 +18014,23 @@ msgstr "" #, c-format msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\"" -msgstr "" -"trasig ewah-bitkarta: avhugget huvud för bitkarta för incheckning \"%s\"" +msgstr "trasig ewah-bitkarta: avhugget huvud för bitkarta för incheckning â€%sâ€" + +#, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "kunde inte läsa paketet: â€%sâ€, inaktiverar Ã¥teranvändning av paket" #, c-format msgid "object '%s' not found in type bitmaps" -msgstr "objektet \"%s\" hittades inte i typbitkartor" +msgstr "objektet â€%s†hittades inte i typbitkartor" #, c-format msgid "object '%s' does not have a unique type" -msgstr "objektet \"%s\" har inte en unik typ" +msgstr "objektet â€%s†har inte en unik typ" #, c-format msgid "object '%s': real type '%s', expected: '%s'" -msgstr "objektet \"%s\": riktig typ \"%s\", förväntade \"%s\"" +msgstr "objektet â€%sâ€: riktig typ â€%sâ€, förväntade â€%sâ€" #, c-format msgid "object not in bitmap: '%s'" @@ -17868,22 +18044,22 @@ msgstr "du mÃ¥ste ange exakt en incheckning att testa" #, c-format msgid "commit '%s' doesn't have an indexed bitmap" -msgstr "incheckningen \"%s\" har inte en indexerad bitkarta" +msgstr "incheckningen â€%s†har inte en indexerad bitkarta" msgid "mismatch in bitmap results" msgstr "bitkarteresultat stämmer inte överens" #, c-format msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>" -msgstr "kunde inte hitta \"%s\" i paketet \"%s\" pÃ¥ offset %<PRIuMAX>" +msgstr "kunde inte hitta â€%s†i paketet â€%s†pÃ¥ offset %<PRIuMAX>" #, c-format msgid "unable to get disk usage of '%s'" -msgstr "kan inte hämta diskanvändning för \"%s\"" +msgstr "kan inte hämta diskanvändning för â€%sâ€" #, c-format msgid "bitmap file '%s' has invalid checksum" -msgstr "bitkartefilen \"%s\" har ogiltig kontrollsumma" +msgstr "bitkartefilen â€%s†har ogiltig kontrollsumma" #, c-format msgid "mtimes file %s is too small" @@ -17932,6 +18108,12 @@ msgstr "ogiltig kontrollsumma" msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "ogiltig rev-indexposition vid %<PRIu64>: %<PRIu32> != %<PRIu32>" +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "baklängesindex-stycke för multi-pack-index har fel storlek" + +msgid "could not determine preferred pack" +msgstr "kunde inte bestämma föredraget paket" + msgid "cannot both write and verify reverse index" msgstr "kan inte bÃ¥de skriva och bekräfta reverse-index" @@ -17945,7 +18127,7 @@ msgstr "kunde inte göra %s läsbar" #, c-format msgid "could not write '%s' promisor file" -msgstr "kunde inte skriva kontraktsfilen \"%s\"" +msgstr "kunde inte skriva kontraktsfilen â€%sâ€" msgid "offset before end of packfile (broken .idx?)" msgstr "offset före slutet av packfilen (trasig .idx?)" @@ -17964,34 +18146,25 @@ msgstr "offset borton slutet av packindex för %s (trunkerat index?)" #, c-format msgid "malformed expiration date '%s'" -msgstr "trasigt utlöpsdatum: \"%s\"" +msgstr "trasigt utlöpsdatum: â€%sâ€" #, c-format msgid "option `%s' expects \"always\", \"auto\", or \"never\"" -msgstr "" -"flaggan \"%s\" antar \"always\" (alltid), \"auto\" eller \"never\" (aldrig)" +msgstr "flaggan â€%s†antar â€always†(alltid), â€auto†eller â€never†(aldrig)" #, c-format msgid "malformed object name '%s'" -msgstr "felformat objektnamn \"%s\"" +msgstr "felformat objektnamn â€%sâ€" #, c-format msgid "option `%s' expects \"%s\" or \"%s\"" -msgstr "flaggan \"%s\" kräver \"%s\" eller \"%s\"" +msgstr "flaggan â€%s†kräver â€%s†eller â€%sâ€" #, c-format msgid "%s requires a value" msgstr "%s behöver ett värde" #, c-format -msgid "%s is incompatible with %s" -msgstr "%s är inkompatibel med %s" - -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s: inkompatibelt med nÃ¥got annat" - -#, c-format msgid "%s takes no value" msgstr "%s tar inget värde" @@ -18009,7 +18182,7 @@ msgstr "tvetydig flagga: %s (kan vara --%s%s eller --%s%s)" #, c-format msgid "did you mean `--%s` (with two dashes)?" -msgstr "menade du \"--%s\" (med tvÃ¥ bindestreck)?" +msgstr "menade du â€--%s†(med tvÃ¥ bindestreck)?" #, c-format msgid "alias of --%s" @@ -18020,15 +18193,15 @@ msgstr "behöver ett underkommando" #, c-format msgid "unknown option `%s'" -msgstr "okänd flagga \"%s\"" +msgstr "okänd flagga â€%sâ€" #, c-format msgid "unknown switch `%c'" -msgstr "okänd flagga \"%c\"" +msgstr "okänd flagga â€%câ€" #, c-format msgid "unknown non-ascii option in string: `%s'" -msgstr "okänd icke-ascii-flagga i strängen: \"%s\"" +msgstr "okänd icke-ascii-flagga i strängen: â€%sâ€" msgid "..." msgstr "..." @@ -18074,6 +18247,10 @@ msgstr " %s" msgid "-NUM" msgstr "-TAL" +#, c-format +msgid "opposite of --no-%s" +msgstr "motsatsen mot --no-%s" + msgid "expiry-date" msgstr "giltig-till" @@ -18103,14 +18280,22 @@ msgid "" msgstr "med --pathspec-from-file, sökvägsangivelser avdelas med NUL-tecken" #, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "felaktigt booleskt miljövariabelvärde â€%s†för â€%sâ€" + +#, c-format +msgid "failed to parse %s" +msgstr "kunde inte tolka %s" + +#, c-format msgid "Could not make %s writable by group" msgstr "Kunde inte göra %s skrivbar för gruppen" msgid "Escape character '\\' not allowed as last character in attr value" -msgstr "Specialtecknet \"\\\" tillÃ¥ts inte som sista tecken i attributvärde" +msgstr "Specialtecknet â€\\†tillÃ¥ts inte som sista tecken i attributvärde" msgid "Only one 'attr:' specification is allowed." -msgstr "Endast en \"attr:\"-angivelse tillÃ¥ten." +msgstr "Endast en â€attr:â€-angivelse tillÃ¥ten." msgid "attr spec must not be empty" msgstr "attr-angivelse kan inte vara tom" @@ -18120,42 +18305,45 @@ msgid "invalid attribute name %s" msgstr "ogiltigt attributnamn %s" msgid "global 'glob' and 'noglob' pathspec settings are incompatible" -msgstr "" -"de globala sökvägsinställningarna \"glob\" och \"noglob\" är inkompatibla" +msgstr "de globala sökvägsinställningarna â€glob†och â€noglob†är inkompatibla" msgid "" "global 'literal' pathspec setting is incompatible with all other global " "pathspec settings" msgstr "" -"den globala sökvägsinställningen \"literal\" är inkompatibel med alla andra " +"den globala sökvägsinställningen â€literal†är inkompatibel med alla andra " "globala sökvägsinställningar" msgid "invalid parameter for pathspec magic 'prefix'" -msgstr "ogiltig parameter för sökvägsuttrycket för \"prefix\"" +msgstr "ogiltig parameter för sökvägsuttrycket för â€prefixâ€" #, c-format msgid "Invalid pathspec magic '%.*s' in '%s'" -msgstr "Felaktigt sökvägsuttryck \"%.*s\" i \"%s\"" +msgstr "Felaktigt sökvägsuttryck â€%.*s†i â€%sâ€" #, c-format msgid "Missing ')' at the end of pathspec magic in '%s'" -msgstr "\")\" saknas i slutet av sökvägsuttrycket för \"%s\"" +msgstr "â€)†saknas i slutet av sökvägsuttrycket för â€%sâ€" #, c-format msgid "Unimplemented pathspec magic '%c' in '%s'" -msgstr "Ej implementerat sökvägsuttryckmagi \"%c\" i \"%s\"" +msgstr "Ej implementerat sökvägsuttryckmagi â€%c†i â€%sâ€" #, c-format msgid "%s: 'literal' and 'glob' are incompatible" -msgstr "%s: \"literal\" och \"glob\" är inkompatibla" +msgstr "%s: â€literal†och â€glob†är inkompatibla" + +#, c-format +msgid "'%s' is outside the directory tree" +msgstr "â€%s†är utanför katalogträdet" #, c-format msgid "%s: '%s' is outside repository at '%s'" -msgstr "%s: \"%s\" är utanför arkivet pÃ¥ \"%s\"" +msgstr "%s: â€%s†är utanför arkivet pÃ¥ â€%sâ€" #, c-format msgid "'%s' (mnemonic: '%c')" -msgstr "\"%s\" (minnesstöd: \"%c\")" +msgstr "â€%s†(minnesstöd: â€%câ€)" #, c-format msgid "%s: pathspec magic not supported by this command: %s" @@ -18163,7 +18351,7 @@ msgstr "%s: sökvägsuttrycket hanteras inte av det här kommandot: %s" #, c-format msgid "pathspec '%s' is beyond a symbolic link" -msgstr "sökvägsangivelsen \"%s\" är pÃ¥ andra sidan av en symbolisk länk" +msgstr "sökvägsangivelsen â€%s†är pÃ¥ andra sidan av en symbolisk länk" #, c-format msgid "line is badly quoted: %s" @@ -18179,7 +18367,7 @@ msgid "unable to write response end packet" msgstr "kunde inte skriva svarsavslutningspaket" msgid "flush packet write failed" -msgstr "fel vid skrivning av \"flush\"-paket" +msgstr "fel vid skrivning av â€flushâ€-paket" msgid "protocol error: impossibly long line" msgstr "protokollfel: omöjligt lÃ¥ng rad" @@ -18234,57 +18422,56 @@ msgstr "" #, c-format msgid "promisor remote name cannot begin with '/': %s" -msgstr "kontraktsfjärr kan inte börja med \"/\": %s" +msgstr "kontraktsfjärr kan inte börja med â€/â€: %s" #, c-format msgid "could not fetch %s from promisor remote" msgstr "kunde inte hämta %s frÃ¥n kontraktsfjärr" msgid "object-info: expected flush after arguments" -msgstr "object-info: förväntade \"flush\" efter argument" +msgstr "object-info: förväntade â€flush†efter argument" msgid "Removing duplicate objects" msgstr "Tar bort duplicerade objekt" msgid "could not start `log`" -msgstr "kunde inte starta \"log\"" +msgstr "kunde inte starta â€logâ€" msgid "could not read `log` output" -msgstr "kunde inte läsa utdata frÃ¥n \"log\"" +msgstr "kunde inte läsa utdata frÃ¥n â€logâ€" #, c-format msgid "could not parse commit '%s'" -msgstr "kunde inte tolka incheckningen \"%s\"" +msgstr "kunde inte tolka incheckningen â€%sâ€" #, c-format msgid "" "could not parse first line of `log` output: did not start with 'commit ': " "'%s'" msgstr "" -"kunde inte tolka första raden i \"log\"-updata: börjar inte med \"commit \": " -"\"%s\"" +"kunde inte tolka första raden i â€logâ€-updata: börjar inte med â€commit â€: â€%sâ€" #, c-format msgid "could not parse git header '%.*s'" -msgstr "kunde inte tolka git-huvudet \"%.*s\"" +msgstr "kunde inte tolka git-huvudet â€%.*sâ€" msgid "failed to generate diff" msgstr "misslyckades skapa diff" #, c-format msgid "could not parse log for '%s'" -msgstr "kunde inte tolka loggen för \"%s\"" +msgstr "kunde inte tolka loggen för â€%sâ€" #, c-format msgid "invalid extra cruft tip: '%s'" -msgstr "ogiltig extra överbliven ände: \"%s\"" +msgstr "ogiltig extra överbliven ände: â€%sâ€" msgid "unable to enumerate additional recent objects" msgstr "kan inte räkna ytterligare nyliga objekt" #, c-format msgid "will not add file alias '%s' ('%s' already exists in index)" -msgstr "lägger inte till filalias \"%s\" (\"%s\" finns redan i indexet)" +msgstr "lägger inte till filalias â€%s†(â€%s†finns redan i indexet)" msgid "cannot create an empty blob in the object database" msgstr "kan inte skapa tom blob i objektdatabasen" @@ -18296,19 +18483,15 @@ msgstr "" #, c-format msgid "unable to index file '%s'" -msgstr "kan inte indexera filen \"%s\"" +msgstr "kan inte indexera filen â€%sâ€" #, c-format msgid "unable to add '%s' to index" -msgstr "kan inte lägga till \"%s\" till indexet" - -#, c-format -msgid "unable to stat '%s'" -msgstr "kan inte ta status pÃ¥ \"%s\"" +msgstr "kan inte lägga till â€%s†till indexet" #, c-format msgid "'%s' appears as both a file and as a directory" -msgstr "\"%s\" finns bÃ¥de som en fil och en katalog" +msgstr "â€%s†finns bÃ¥de som en fil och en katalog" msgid "Refresh index" msgstr "Uppdatera indexet" @@ -18354,18 +18537,18 @@ msgstr "okänt format 0x%08x pÃ¥ indexpost" #, c-format msgid "malformed name field in the index, near path '%s'" -msgstr "felformat namnfält i indexet, nära sökvägen \"%s\"" +msgstr "felformat namnfält i indexet, nära sökvägen â€%sâ€" msgid "unordered stage entries in index" msgstr "osorterade köposter i index" #, c-format msgid "multiple stage entries for merged file '%s'" -msgstr "flera köposter för den sammanslagna filen \"%s\"" +msgstr "flera köposter för den sammanslagna filen â€%sâ€" #, c-format msgid "unordered stage entries for '%s'" -msgstr "osorterade köposter för \"%s\"" +msgstr "osorterade köposter för â€%sâ€" #, c-format msgid "unable to create load_cache_entries thread: %s" @@ -18401,7 +18584,7 @@ msgstr "kunde inte utföra join pÃ¥ load_index_extensions-trÃ¥den: %s" #, c-format msgid "could not freshen shared index '%s'" -msgstr "kunde inte uppdatera delat index \"%s\"" +msgstr "kunde inte uppdatera delat index â€%sâ€" #, c-format msgid "broken index, expect %s in %s, got %s" @@ -18414,10 +18597,6 @@ msgid "failed to convert to a sparse-index" msgstr "misslyckades omvandla till glest index" #, c-format -msgid "could not stat '%s'" -msgstr "kunde inte ta status pÃ¥ \"%s\"" - -#, c-format msgid "unable to open git dir: %s" msgstr "kunde inte öppna git-katalog: %s" @@ -18427,7 +18606,7 @@ msgstr "misslyckades ta bort länken: %s" #, c-format msgid "cannot fix permission bits on '%s'" -msgstr "kan inte rätta behörighetsbitar pÃ¥ \"%s\"" +msgstr "kan inte rätta behörighetsbitar pÃ¥ â€%sâ€" #, c-format msgid "%s: cannot drop to stage #0" @@ -18439,16 +18618,16 @@ msgstr "diff-status %c förväntades inte" #, c-format msgid "remove '%s'\n" -msgstr "ta bort \"%s\"\n" +msgstr "ta bort â€%sâ€\n" 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 "" -"Du kan rätta detta med \"git rebase --edit-todo\" följt av \"git rebase --" -"continue\".\n" -"Avbryt ombaseringen med \"git rebase --abort\".\n" +"Du kan rätta detta med â€git rebase --edit-todo†följt av â€git rebase --" +"continueâ€.\n" +"Avbryt ombaseringen med â€git rebase --abortâ€.\n" #, c-format msgid "" @@ -18490,18 +18669,17 @@ msgstr "" "e, edit <incheckning> = använd incheckning, men stanna för tillägg\n" "s, squash <incheckning> = använd incheckning, men infoga i föregÃ¥ende " "incheckning\n" -"f, fixup [-C | -c] <incheckning> = som \"squash\" men behÃ¥ll bara " +"f, fixup [-C | -c] <incheckning> = som â€squash†men behÃ¥ll bara " "loggmeddelandet\n" " frÃ¥n föregÃ¥ende incheckning, sÃ¥vida inte -C används, dÃ¥ " "används\n" " istället bara den här incheckningens meddelande; -c är " "samma\n" " som -C, men öppnar redigeringsprogrammet\n" -"f, fixup <incheckning> = som \"squash\", men förkasta " -"incheckningsmeddelandet\n" +"f, fixup <incheckning> = som â€squashâ€, men förkasta incheckningsmeddelandet\n" "x, exec <kommando> = kör kommando (resten av raden) i skalet\n" -"b, break = stoppa här (fortsätt ombaseringen senare med \"git rebase --" -"continue\")\n" +"b, break = stoppa här (fortsätt ombaseringen senare med â€git rebase --" +"continueâ€)\n" "d, drop <incheckning> = ta bort incheckning\n" "l, label <etikett> = ge aktuellt HEAD ett namn\n" "t, reset <etikett> = Ã¥terställ HEAD till en etikett\n" @@ -18526,7 +18704,7 @@ msgid "" "Do not remove any line. Use 'drop' explicitly to remove a commit.\n" msgstr "" "\n" -"Ta inte bort rader. Använd \"drop\" för att specifikt förkasta en " +"Ta inte bort rader. Använd â€drop†för att specifikt förkasta en " "incheckning.\n" msgid "" @@ -18544,7 +18722,7 @@ msgid "" "\n" msgstr "" "\n" -"Du redigerar \"todo\"-filen för en pÃ¥gÃ¥ende interaktiv ombasering.\n" +"Du redigerar â€todoâ€-filen för en pÃ¥gÃ¥ende interaktiv ombasering.\n" "För att forsätta ombasera efter redigeringen, kör:\n" " git rebase --continue\n" "\n" @@ -18560,7 +18738,7 @@ msgstr "" #, c-format msgid "could not write '%s'." -msgstr "kunde inte skriva \"%s\"." +msgstr "kunde inte skriva â€%sâ€." #, c-format msgid "" @@ -18579,19 +18757,16 @@ msgid "" "The possible behaviours are: ignore, warn, error.\n" "\n" msgstr "" -"För att undvika det här meddelandet kan du använda \"drop\" för att " -"explicit\n" +"För att undvika det här meddelandet kan du använda â€drop†för att explicit\n" "kasta en incheckning.\n" "\n" -"Använd \"git config rebase.missingCommitsCheck\" för att ändra " -"varningsnivÃ¥n.\n" -"Möjliga bettenden är: \"ignore\" (ignorera), \"warn\" (varna), \"error" -"\" (fel).\n" +"Använd â€git config rebase.missingCommitsCheck†för att ändra varningsnivÃ¥n.\n" +"Möjliga bettenden är: â€ignore†(ignorera), â€warn†(varna), â€error†(fel).\n" "\n" #, c-format msgid "%s: 'preserve' superseded by 'merges'" -msgstr "%s: \"preserve\" har ersatts av \"merges\"" +msgstr "%s: â€preserve†har ersatts av â€mergesâ€" msgid "gone" msgstr "försvunnen" @@ -18662,7 +18837,7 @@ msgstr "vädre förväntades %s=" #, c-format msgid "positive value expected '%s' in %%(%s)" -msgstr "positivt värde förväntat \"%s\" i %%(%s)" +msgstr "positivt värde förväntat â€%s†i %%(%s)" #, c-format msgid "expected format: %%(align:<width>,<position>)" @@ -18699,8 +18874,7 @@ msgstr "okänt fältnamn: %.*s" #, c-format msgid "" "not a git repository, but the field '%.*s' requires access to object data" -msgstr "" -"inte ett git-arkiv, men fältet \"%.*s\" kräver tillgÃ¥ng till objektdata" +msgstr "inte ett git-arkiv, men fältet â€%.*s†kräver tillgÃ¥ng till objektdata" #, c-format msgid "format: %%(%s) atom used without a %%(%s) atom" @@ -18735,7 +18909,7 @@ msgid "--format=%.*s cannot be used with --python, --shell, --tcl" msgstr "--format=%.*s kan inte användas med --python, --shell, --tcl" msgid "failed to run 'describe'" -msgstr "misslyckades att köra \"describe\"" +msgstr "misslyckades att köra â€describeâ€" #, c-format msgid "(no branch, rebasing %s)" @@ -18747,7 +18921,7 @@ msgstr "(ingen gren, ombaserar frÃ¥nkopplat HEAD %s)" #, c-format msgid "(no branch, bisect started on %s)" -msgstr "(ingen gren, \"bisect\" startad pÃ¥ %s)" +msgstr "(ingen gren, â€bisect†startad pÃ¥ %s)" #, c-format msgid "(HEAD detached at %s)" @@ -18770,7 +18944,7 @@ msgstr "parse_object_buffer misslyckades pÃ¥ %s för %s" #, c-format msgid "malformed object at '%s'" -msgstr "felformat objekt vid \"%s\"" +msgstr "felformat objekt vid â€%sâ€" #, c-format msgid "ignoring ref with broken name %s" @@ -18790,7 +18964,7 @@ msgstr "felformat objektnamn %s" #, c-format msgid "option `%s' must point to a commit" -msgstr "flaggan \"%s\" mÃ¥ste peka pÃ¥ en incheckning" +msgstr "flaggan â€%s†mÃ¥ste peka pÃ¥ en incheckning" msgid "key" msgstr "nyckel" @@ -18807,11 +18981,11 @@ msgstr "inte en referenslogg: %s" #, c-format msgid "no reflog for '%s'" -msgstr "ingen referenslogg för \"%s\"" +msgstr "ingen referenslogg för â€%sâ€" #, c-format msgid "%s does not point to a valid object!" -msgstr "\"%s\" pekar inte pÃ¥ ett giltigt objekt!" +msgstr "â€%s†pekar inte pÃ¥ ett giltigt objekt!" #, c-format msgid "" @@ -18826,20 +19000,20 @@ msgid "" "\n" "\tgit branch -m <name>\n" msgstr "" -"Använder \"%s\" som namn för den inledande grenen. Detta förvalda grennamn\n" +"Använder â€%s†som namn för den inledande grenen. Detta förvalda grennamn\n" "kan ändras i framtiden. För att välja vilket namn som ska användas pÃ¥\n" "den inledande grenen i alla nya arkiv, och dölja denna varning, kör du:\n" "\n" "\tgit config --global init.defaultBranch <namn>\n" "\n" -"Namn som ofta används istället för \"master\" är \"main\", \"trunk\" och\n" -"\"development\". Den nyskapade grenen kan ges nytt namn med kommandot:\n" +"Namn som ofta används istället för â€master†är â€mainâ€, â€trunk†och\n" +"â€developmentâ€. Den nyskapade grenen kan ges nytt namn med kommandot:\n" "\n" "\tgit branch -m <namn>\n" #, c-format msgid "could not retrieve `%s`" -msgstr "kunde inte hämta \"%s\"" +msgstr "kunde inte hämta â€%sâ€" #, c-format msgid "invalid branch name: %s = %s" @@ -18863,15 +19037,15 @@ msgstr "loggen för %s är tom" #, c-format msgid "refusing to update ref with bad name '%s'" -msgstr "vägrar uppdatera referens med trasigt namn \"%s\"" +msgstr "vägrar uppdatera referens med trasigt namn â€%sâ€" #, c-format msgid "update_ref failed for ref '%s': %s" -msgstr "update_ref misslyckades för referensen \"%s\": %s" +msgstr "update_ref misslyckades för referensen â€%sâ€: %s" #, c-format msgid "multiple updates for ref '%s' not allowed" -msgstr "flera uppdateringar för referensen \"%s\" tillÃ¥ts inte" +msgstr "flera uppdateringar för referensen â€%s†tillÃ¥ts inte" msgid "ref updates forbidden inside quarantine environment" msgstr "referensuppdateringar förbjudna i karantänmiljö" @@ -18881,15 +19055,11 @@ msgstr "referensuppdateringar avbrutna av krok" #, c-format msgid "'%s' exists; cannot create '%s'" -msgstr "\"%s\" finns; kan inte skapa \"%s\"" +msgstr "â€%s†finns; kan inte skapa â€%sâ€" #, c-format msgid "cannot process '%s' and '%s' at the same time" -msgstr "kan inte hantera \"%s\" och \"%s\" samtidigt" - -#, c-format -msgid "could not remove reference %s" -msgstr "kunde inte ta bort referensen %s" +msgstr "kan inte hantera â€%s†och â€%s†samtidigt" #, c-format msgid "could not delete reference %s: %s" @@ -18901,11 +19071,11 @@ msgstr "kunde inte ta bort referenser: %s" #, c-format msgid "invalid refspec '%s'" -msgstr "felaktig referensspecifikation: \"%s\"" +msgstr "felaktig referensspecifikation: â€%sâ€" #, c-format msgid "invalid quoting in push-option value: '%s'" -msgstr "felaktig citering pÃ¥ värde för push-option: \"%s\"" +msgstr "felaktig citering pÃ¥ värde för push-option: â€%sâ€" #, c-format msgid "%sinfo/refs not valid: is this a git repository?" @@ -18916,23 +19086,23 @@ msgstr "ogiltigt svar frÃ¥n servern; förväntade tjänst, fick flush-paket" #, c-format msgid "invalid server response; got '%s'" -msgstr "ogiltigt svar frÃ¥n servern; fick \"%s\"" +msgstr "ogiltigt svar frÃ¥n servern; fick â€%sâ€" #, c-format msgid "repository '%s' not found" -msgstr "arkivet \"%s\" hittades inte" +msgstr "arkivet â€%s†hittades inte" #, c-format msgid "Authentication failed for '%s'" -msgstr "Autentisering misslyckades \"%s\"" +msgstr "Autentisering misslyckades â€%sâ€" #, c-format msgid "unable to access '%s' with http.pinnedPubkey configuration: %s" -msgstr "kan inte nÃ¥ \"%s\" med http.pinnedPubkey inställt till: %s" +msgstr "kan inte nÃ¥ â€%s†med http.pinnedPubkey inställt till: %s" #, c-format msgid "unable to access '%s': %s" -msgstr "kan inte komma Ã¥t \"%s\": %s" +msgstr "kan inte komma Ã¥t â€%sâ€: %s" #, c-format msgid "redirecting to %s" @@ -18988,18 +19158,18 @@ msgstr "kan inte hämta med sha1 över smart http" #, c-format msgid "protocol error: expected sha/ref, got '%s'" -msgstr "protokollfel: förväntade sha/ref, fick \"%s\"" +msgstr "protokollfel: förväntade sha/ref, fick â€%sâ€" #, c-format msgid "http transport does not support %s" msgstr "http-transporten stöder inte %s" msgid "protocol error: expected '<url> <path>', missing space" -msgstr "protokollfel: förväntade \"<url> <sökväg>\", saknar blanksteg" +msgstr "protokollfel: förväntade â€<url> <sökväg>â€, saknar blanksteg" #, c-format msgid "failed to download file at URL '%s'" -msgstr "misslyckades hämta filen pÃ¥ URL \"%s\"" +msgstr "misslyckades hämta filen pÃ¥ URL â€%sâ€" msgid "git-http-push failed" msgstr "git-http-push misslyckades" @@ -19015,11 +19185,11 @@ msgstr "remote-curl: försökte ta emot utan lokalt arkiv" #, c-format msgid "remote-curl: unknown command '%s' from git" -msgstr "remote-curl: okänt kommando \"%s\" frÃ¥n git" +msgstr "remote-curl: okänt kommando â€%s†frÃ¥n git" #, c-format msgid "config remote shorthand cannot begin with '/': %s" -msgstr "konfigurerad kortform för fjärr kan inte börja med \"/\": %s" +msgstr "konfigurerad kortform för fjärr kan inte börja med â€/â€: %s" msgid "more than one receivepack given, using the first" msgstr "mer än en receivepack angavs, använder den första" @@ -19029,11 +19199,11 @@ msgstr "mer än en uploadpack angavs, använder den första" #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" -msgstr "okänt värde transfer.credentialsInUrl: \"%s\"" +msgstr "okänt värde transfer.credentialsInUrl: â€%sâ€" #, c-format msgid "URL '%s' uses plaintext credentials" -msgstr "URL \"%s\" använder inloggningsuppgifter i klartext" +msgstr "URL â€%s†använder inloggningsuppgifter i klartext" #, c-format msgid "Cannot fetch both %s and %s to %s" @@ -19049,11 +19219,11 @@ msgstr "%s spÃ¥rar bÃ¥de %s och %s" #, c-format msgid "key '%s' of pattern had no '*'" -msgstr "nyckeln \"%s\" i mönstret innehÃ¥ller ingen \"*\"" +msgstr "nyckeln â€%s†i mönstret innehÃ¥ller ingen â€*â€" #, c-format msgid "value '%s' of pattern has no '*'" -msgstr "värdet \"%s\" i mönstret innehÃ¥ller ingen \"*\"" +msgstr "värdet â€%s†i mönstret innehÃ¥ller ingen â€*â€" #, c-format msgid "src refspec %s does not match any" @@ -19080,12 +19250,12 @@ msgid "" "Neither worked, so we gave up. You must fully qualify the ref." msgstr "" "MÃ¥let du angav är inte ett komplett referensamn (dvs.,\n" -"startar med \"refs/\"). Vi försökte gissa vad du menade genom att:\n" +"startar med â€refs/â€). Vi försökte gissa vad du menade genom att:\n" "\n" -"- Se efter en referens som motsvarar \"%s\" pÃ¥ fjärrsidan.\n" -"- Se om <källan> som sänds (\"%s\")\n" -" är en referens i \"refs/{heads,tags}/\". Om sÃ¥ lägger vi till\n" -" motsvarande refs/{heads,tags}/-prefix pÃ¥ fjärrsidan.\n" +"- Se efter en referens som motsvarar â€%s†pÃ¥ fjärrsidan.\n" +"- Se om <källan> som sänds (â€%sâ€)\n" +" är en referens i â€refs/{heads,tags}/â€. Om sÃ¥ lägger vi till\n" +" motsvarande â€refs/{heads,tags}/â€-prefix pÃ¥ fjärrsidan.\n" "\n" "Inget av dem fungerade, sÃ¥ vi gav upp. Ange fullständig referens." @@ -19097,7 +19267,7 @@ msgid "" msgstr "" "<Källa>-delen av ref.spec-en är ett incheckningsobjekt.\n" "Var det meningen att skapa en ny gren genom att sända\n" -"till \"%s:refs/heads/%s\"?" +"till â€%s:refs/heads/%sâ€?" #, c-format msgid "" @@ -19107,7 +19277,7 @@ msgid "" msgstr "" "<Källa>-delen av ref.spec-en är ett taggobjekt.\n" "Var det meningen att skapa en ny tagg genom att sända\n" -"till \"%s:refs/tags/%s\"?" +"till â€%s:refs/tags/%sâ€?" #, c-format msgid "" @@ -19117,7 +19287,7 @@ msgid "" msgstr "" "<Källa>-delen av ref.spec-en är ett trädobjekt.\n" "Var det meningen att tagga ett nytt träd genom att sända\n" -"till \"%s:refs/tags/%s\"?" +"till â€%s:refs/tags/%sâ€?" #, c-format msgid "" @@ -19127,7 +19297,7 @@ msgid "" msgstr "" "<Källa>-delen av ref.spec-en är ett blobobjekt.\n" "Var det meningen att tagga en ny blob genom att sända\n" -"till \"%s:refs/tags/%s\"?" +"till â€%s:refs/tags/%sâ€?" #, c-format msgid "%s cannot be resolved to branch" @@ -19135,48 +19305,48 @@ msgstr "%s kan inte slÃ¥s upp till en gren" #, c-format msgid "unable to delete '%s': remote ref does not exist" -msgstr "kan inte ta bort \"%s\": fjärreferensen finns inte" +msgstr "kan inte ta bort â€%sâ€: fjärreferensen finns inte" #, c-format msgid "dst refspec %s matches more than one" -msgstr "fjärr-referensspecifikationen \"%s\" motsvarar mer än en" +msgstr "fjärr-referensspecifikationen â€%s†motsvarar mer än en" #, c-format msgid "dst ref %s receives from more than one src" -msgstr "fjärr-referensen \"%s\" hämtar frÃ¥n mer än en källa" +msgstr "fjärr-referensen â€%s†hämtar frÃ¥n mer än en källa" msgid "HEAD does not point to a branch" msgstr "HEAD pekar inte pÃ¥ en gren" #, c-format msgid "no such branch: '%s'" -msgstr "okänd gren: \"%s\"" +msgstr "okänd gren: â€%sâ€" #, c-format msgid "no upstream configured for branch '%s'" -msgstr "ingen standarduppström angiven för grenen \"%s\"" +msgstr "ingen standarduppström angiven för grenen â€%sâ€" #, c-format msgid "upstream branch '%s' not stored as a remote-tracking branch" -msgstr "uppströmsgrenen \"%s\" är inte lagrad som en fjärrspÃ¥rande gren" +msgstr "uppströmsgrenen â€%s†är inte lagrad som en fjärrspÃ¥rande gren" #, c-format msgid "push destination '%s' on remote '%s' has no local tracking branch" -msgstr "push-mÃ¥let \"%s\" pÃ¥ fjärren \"%s\" har ingen lokalt spÃ¥rande gren" +msgstr "push-mÃ¥let â€%s†pÃ¥ fjärren â€%s†har ingen lokalt spÃ¥rande gren" #, c-format msgid "branch '%s' has no remote for pushing" -msgstr "grenen \"%s\" har ingen fjärr för \"push\"" +msgstr "grenen â€%s†har ingen fjärr för â€pushâ€" #, c-format msgid "push refspecs for '%s' do not include '%s'" -msgstr "\"push\"-referensspecifikation för \"%s\" innehÃ¥ller inte \"%s\"" +msgstr "â€pushâ€-referensspecifikation för â€%s†innehÃ¥ller inte â€%sâ€" msgid "push has no destination (push.default is 'nothing')" -msgstr "\"push\" har inget mÃ¥l (push.default är \"ingenting\")" +msgstr "â€push†har inget mÃ¥l (push.default är â€ingentingâ€)" msgid "cannot resolve 'simple' push to a single destination" -msgstr "\"enkel push\" motsvarar flera olika mÃ¥l" +msgstr "â€enkel push†motsvarar flera olika mÃ¥l" #, c-format msgid "couldn't find remote ref %s" @@ -19184,47 +19354,47 @@ msgstr "Kunde inte hitta fjärr-referensen %s" #, c-format msgid "* Ignoring funny ref '%s' locally" -msgstr "* Ignorerar märklig referens \"%s\" lokalt" +msgstr "* Ignorerar märklig referens â€%s†lokalt" #, c-format msgid "Your branch is based on '%s', but the upstream is gone.\n" -msgstr "Din gren är baserad pÃ¥ \"%s\", men den har försvunnit uppströms.\n" +msgstr "Din gren är baserad pÃ¥ â€%sâ€, men den har försvunnit uppströms.\n" msgid " (use \"git branch --unset-upstream\" to fixup)\n" -msgstr " (använd \"git branch --unset-upstream\" för att rätta)\n" +msgstr " (använd â€git branch --unset-upstream†för att rätta)\n" #, c-format msgid "Your branch is up to date with '%s'.\n" -msgstr "Din gren är à jour med \"%s\".\n" +msgstr "Din gren är à jour med â€%sâ€.\n" #, c-format msgid "Your branch and '%s' refer to different commits.\n" -msgstr "Din gren och \"%s\" pekar pÃ¥ olika incheckningar.\n" +msgstr "Din gren och â€%s†pekar pÃ¥ olika incheckningar.\n" #, c-format msgid " (use \"%s\" for details)\n" -msgstr " (använd \"%s\" för detaljer)\n" +msgstr " (använd â€%s†för detaljer)\n" #, 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] "Din gren ligger före \"%s\" med %d incheckning.\n" -msgstr[1] "Din gren ligger före \"%s\" med %d incheckningar.\n" +msgstr[0] "Din gren ligger före â€%s†med %d incheckning.\n" +msgstr[1] "Din gren ligger före â€%s†med %d incheckningar.\n" msgid " (use \"git push\" to publish your local commits)\n" -msgstr " (använd \"git push\" för att publicera dina lokala incheckningar)\n" +msgstr " (använd â€git push†för att publicera dina lokala incheckningar)\n" #, 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] "" -"Din gren ligger efter \"%s\" med %d incheckning, och kan snabbspolas.\n" +"Din gren ligger efter â€%s†med %d incheckning, och kan snabbspolas.\n" msgstr[1] "" -"Din gren ligger efter \"%s\" med %d incheckningar, och kan snabbspolas.\n" +"Din gren ligger efter â€%s†med %d incheckningar, och kan snabbspolas.\n" msgid " (use \"git pull\" to update your local branch)\n" -msgstr " (använd \"git pull\" för att uppdatera din lokala gren)\n" +msgstr " (använd â€git pull†för att uppdatera din lokala gren)\n" #, c-format msgid "" @@ -19234,24 +19404,23 @@ msgid_plural "" "Your branch and '%s' have diverged,\n" "and have %d and %d different commits each, respectively.\n" msgstr[0] "" -"Din gren och \"%s\" har divergerat,\n" +"Din gren och â€%s†har divergerat,\n" "och har %d respektive %d olika incheckning.\n" msgstr[1] "" -"Din gren och \"%s\" har divergerat,\n" +"Din gren och â€%s†har divergerat,\n" "och har %d respektive %d olika incheckningar.\n" msgid "" " (use \"git pull\" if you want to integrate the remote branch with yours)\n" -msgstr "" -" (använd \"git pull\" om du vill integrera fjärrgrenen med din egen)\n" +msgstr " (använd â€git pull†om du vill integrera fjärrgrenen med din egen)\n" #, c-format msgid "cannot parse expected object name '%s'" -msgstr "kan inte tolka förväntat objektnamn \"%s\"" +msgstr "kan inte tolka förväntat objektnamn â€%sâ€" #, c-format msgid "cannot strip one component off url '%s'" -msgstr "kan inte ta bort en komponent frÃ¥n url:en \"%s\"" +msgstr "kan inte ta bort en komponent frÃ¥n url:en â€%sâ€" #, c-format msgid "bad replace ref name: %s" @@ -19273,55 +19442,55 @@ msgstr "kunde inte skriva rerere-post" #, c-format msgid "there were errors while writing '%s' (%s)" -msgstr "fel vid skrivning av \"%s\" (%s)" +msgstr "fel vid skrivning av â€%s†(%s)" #, c-format msgid "could not parse conflict hunks in '%s'" -msgstr "kunde inte tolka konflikt-stycket i \"%s\"" +msgstr "kunde inte tolka konflikt-stycket i â€%sâ€" #, c-format msgid "failed utime() on '%s'" -msgstr "\"utime()\" misslyckades pÃ¥ \"%s\"" +msgstr "â€utime()†misslyckades pÃ¥ â€%sâ€" #, c-format msgid "writing '%s' failed" -msgstr "misslyckades skriva \"%s\"" +msgstr "misslyckades skriva â€%sâ€" #, c-format msgid "Staged '%s' using previous resolution." -msgstr "Köade \"%s\" med sparad lösning." +msgstr "Köade â€%s†med sparad lösning." #, c-format msgid "Recorded resolution for '%s'." -msgstr "Sparade lösning för \"%s\"." +msgstr "Sparade lösning för â€%sâ€." #, c-format msgid "Resolved '%s' using previous resolution." -msgstr "Löste \"%s\" med tidigare lösning." +msgstr "Löste â€%s†med tidigare lösning." #, c-format msgid "cannot unlink stray '%s'" -msgstr "kan inte ta bort lös länk \"%s\"" +msgstr "kan inte ta bort lös länk â€%sâ€" #, c-format msgid "Recorded preimage for '%s'" -msgstr "Sparade förhandsbild för \"%s\"" +msgstr "Sparade förhandsbild för â€%sâ€" #, c-format msgid "failed to update conflicted state in '%s'" -msgstr "misslyckades uppdatera tillstÃ¥nd för sammanslagningsproblem i \"%s\"" +msgstr "misslyckades uppdatera tillstÃ¥nd för sammanslagningsproblem i â€%sâ€" #, c-format msgid "no remembered resolution for '%s'" -msgstr "inget sparat sammanslagningsresultat för \"%s\"" +msgstr "inget sparat sammanslagningsresultat för â€%sâ€" #, c-format msgid "Updated preimage for '%s'" -msgstr "Uppdaterade förhandsbild för \"%s\"" +msgstr "Uppdaterade förhandsbild för â€%sâ€" #, c-format msgid "Forgot resolution for '%s'\n" -msgstr "Glömde lösning för \"%s\"\n" +msgstr "Glömde lösning för â€%sâ€\n" msgid "unable to open rr-cache directory" msgstr "kan inte uppdatera katalogen rr-cache" @@ -19345,25 +19514,25 @@ msgstr "--exclude-hidden= angavs mer än en gÃ¥ng" #, c-format msgid "resolve-undo records `%s` which is missing" -msgstr "resolve-undo registrerar \"%s\" som saknas" +msgstr "resolve-undo registrerar â€%s†som saknas" #, c-format msgid "could not get commit for ancestry-path argument %s" -msgstr "kunde inte hämta incheckning för \"ancestry-path\"-argumentet %s" +msgstr "kunde inte hämta incheckning för â€ancestry-pathâ€-argumentet %s" msgid "--unpacked=<packfile> no longer supported" msgstr "--unpacked=<paketfil> stöds inte längre" #, c-format msgid "invalid option '%s' in --stdin mode" -msgstr "ogiltig flagga \"%s\" i --stdin-läge" +msgstr "ogiltig flagga â€%s†i --stdin-läge" msgid "your current branch appears to be broken" msgstr "din nuvarande gren verkar vara trasig" #, c-format msgid "your current branch '%s' does not have any commits yet" -msgstr "din nuvarande gren \"%s\" innehÃ¥ller ännu inte nÃ¥gra incheckningar" +msgstr "din nuvarande gren â€%s†innehÃ¥ller ännu inte nÃ¥gra incheckningar" msgid "object filtering requires --objects" msgstr "objektfiltrering kräver --objects" @@ -19377,11 +19546,11 @@ msgstr "kan inte skapa asynkron trÃ¥d: %s" #, c-format msgid "'%s' does not exist" -msgstr "\"%s\" finns inte" +msgstr "â€%s†finns inte" #, c-format msgid "could not switch to '%s'" -msgstr "kunde inte växla till \"%s\"" +msgstr "kunde inte växla till â€%sâ€" msgid "need a working directory" msgstr "behöver en arbetskatalog" @@ -19416,7 +19585,7 @@ msgstr "kunde inte ta bort enrollering" #, c-format msgid "remote HEAD is not a branch: '%.*s'" -msgstr "HEAD hos fjärren är inte en gren: \"%.*s\"" +msgstr "HEAD hos fjärren är inte en gren: â€%.*sâ€" msgid "failed to get default branch name from remote; using local default" msgstr "" @@ -19443,28 +19612,35 @@ msgstr "skapa komplett arbetskatalog vid kloning" msgid "only download metadata for the branch that will be checked out" msgstr "hämta endast metadata för grenen som skall checkas ut" -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [<flaggor>] [--] <arkiv> [<kat>]" +msgid "create repository within 'src' directory" +msgstr "skapa arkiv inuti katalogen â€srcâ€" + +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <huvudgren>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enrollering>]" #, c-format msgid "cannot deduce worktree name from '%s'" -msgstr "Kan inte härleda arbetsträdsnamn frÃ¥n \"%s\"" +msgstr "Kan inte härleda arbetsträdsnamn frÃ¥n â€%sâ€" #, c-format msgid "directory '%s' exists already" -msgstr "katalogen \"%s\" finns redan" +msgstr "katalogen â€%s†finns redan" #, c-format msgid "failed to get default branch for '%s'" -msgstr "misslyckades hämta standardgren för \"%s\"" +msgstr "misslyckades hämta standardgren för â€%sâ€" #, c-format msgid "could not configure remote in '%s'" -msgstr "kunde inte ställa in fjärr i \"%s\"" +msgstr "kunde inte ställa in fjärr i â€%sâ€" #, c-format msgid "could not configure '%s'" -msgstr "kunde inte ställa in \"%s\"" +msgstr "kunde inte ställa in â€%sâ€" msgid "partial clone failed; attempting full clone" msgstr "delvis klon misslyckades; försöker med fullständig klon" @@ -19476,7 +19652,7 @@ msgid "scalar diagnose [<enlistment>]" msgstr "scalar diagnose [<enrollering>]" msgid "`scalar list` does not take arguments" -msgstr "\"scalar list\" tar inte argument" +msgstr "â€scalar list†tar inte argument" msgid "scalar register [<enlistment>]" msgstr "scalar register [<enrollering>]" @@ -19492,15 +19668,31 @@ msgstr "--all eller <enrollering>, men inte bägge" #, c-format msgid "could not remove stale scalar.repo '%s'" -msgstr "kunde inte ta bort gammal scalar.repo \"%s\"" +msgstr "kunde inte ta bort gammal scalar.repo â€%sâ€" + +#, c-format +msgid "removed stale scalar.repo '%s'" +msgstr "tog bort gammal scalar.repo â€%sâ€" + +#, c-format +msgid "repository at '%s' has different owner" +msgstr "arkivet â€%s†har en annan ägare" + +#, c-format +msgid "repository at '%s' has a format issue" +msgstr "arkivet â€%s†har ett formatproblem" #, c-format -msgid "removing stale scalar.repo '%s'" -msgstr "tar bort gammal scalar.repo \"%s\"" +msgid "repository not found in '%s'" +msgstr "arkivet hittades inte i â€%sâ€" #, c-format -msgid "git repository gone in '%s'" -msgstr "git-arkiv försvunnet i \"%s\"" +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"för att avregistrera arkivet frÃ¥n Scalar, kör\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" msgid "" "scalar run <task> [<enlistment>]\n" @@ -19511,7 +19703,7 @@ msgstr "" #, c-format msgid "no such task: '%s'" -msgstr "okänd uppgift: \"%s\"" +msgstr "okänd uppgift: â€%sâ€" msgid "scalar unregister [<enlistment>]" msgstr "scalar unregister [<enrollering>]" @@ -19536,7 +19728,7 @@ msgstr "-C kräver en <katalog>" #, c-format msgid "could not change to '%s'" -msgstr "kunde inte byta till \"%s\"" +msgstr "kunde inte byta till â€%sâ€" msgid "-c requires a <key>=<value> argument" msgstr "-c kräver ett argument pÃ¥ formen <nyckel>=<värde>" @@ -19591,11 +19783,11 @@ msgstr "mottagarsidan stöder inte push-flaggor" #, c-format msgid "invalid commit message cleanup mode '%s'" -msgstr "felaktigt incheckningsmeddelandestädningsläge \"%s\"" +msgstr "felaktigt incheckningsmeddelandestädningsläge â€%sâ€" #, c-format msgid "could not delete '%s'" -msgstr "kunde inte ta bort \"%s\"" +msgstr "kunde inte ta bort â€%sâ€" msgid "revert" msgstr "revert" @@ -19615,7 +19807,7 @@ msgid "" "with 'git add <paths>' or 'git rm <paths>'" msgstr "" "efter att ha löst konflikterna, markera de rättade sökvägarna\n" -"med \"git add <sökvägar>\" eller \"git rm <sökvägar>\"" +"med â€git add <sökvägar>†eller â€git rm <sökvägar>â€" msgid "" "After resolving the conflicts, mark them with\n" @@ -19626,11 +19818,11 @@ msgid "" "run \"git cherry-pick --abort\"." msgstr "" "Efter att ha löst konflikterna, märk dem med\n" -"\"git add/rm <sökvägsangivelse>\" och kör sedan\n" -"\"git cherry-pick --continue\".\n" -"Du kan hoppa över incheckningen istället med \"git cherry-pick --skip\"\n" -"För att avbryta och Ã¥tergÃ¥ till där du var före \"git cherry-pick\",\n" -"kör \"git cherry-pick --abort\"." +"â€git add/rm <sökvägsangivelse>†och kör sedan\n" +"â€git cherry-pick --continueâ€.\n" +"Du kan hoppa över incheckningen istället med â€git cherry-pick --skipâ€\n" +"För att avbryta och Ã¥tergÃ¥ till där du var före â€git cherry-pickâ€,\n" +"kör â€git cherry-pick --abortâ€." msgid "" "After resolving the conflicts, mark them with\n" @@ -19641,30 +19833,30 @@ msgid "" "run \"git revert --abort\"." msgstr "" "Efter att ha löst konflikterna, märk dem med\n" -"\"git add/rm <sökvägsangivelse>\" och kör sedan\n" -"\"git revert --continue\".\n" -"Du kan hoppa över incheckningen istället med \"git revert --skip\"\n" -"För att avbryta och Ã¥tergÃ¥ till där du var före \"git revert\",\n" -"kör \"git revert --abort\"." +"â€git add/rm <sökvägsangivelse>†och kör sedan\n" +"â€git revert --continueâ€.\n" +"Du kan hoppa över incheckningen istället med â€git revert --skipâ€\n" +"För att avbryta och Ã¥tergÃ¥ till där du var före â€git revertâ€,\n" +"kör â€git revert --abortâ€." #, c-format msgid "could not lock '%s'" -msgstr "kunde inte lÃ¥sa \"%s\"" +msgstr "kunde inte lÃ¥sa â€%sâ€" #, c-format msgid "could not write eol to '%s'" -msgstr "kunde inte skriva radslut till \"%s\"" +msgstr "kunde inte skriva radslut till â€%sâ€" #, c-format msgid "failed to finalize '%s'" -msgstr "misslyckades färdigställa \"%s\"" +msgstr "misslyckades färdigställa â€%sâ€" #, c-format msgid "your local changes would be overwritten by %s." msgstr "dina lokala ändringar skulle skrivas över av %s." msgid "commit your changes or stash them to proceed." -msgstr "checka in dina ändringar eller använd \"stash\" för att fortsätta." +msgstr "checka in dina ändringar eller använd â€stash†för att fortsätta." #. TRANSLATORS: %s will be "revert", "cherry-pick" or #. "rebase". @@ -19681,33 +19873,33 @@ msgstr "kunde inte bestämma HEAD:s incheckning" #, c-format msgid "no key present in '%.*s'" -msgstr "ingen nyckel i \"%.*s\"" +msgstr "ingen nyckel i â€%.*sâ€" #, c-format msgid "unable to dequote value of '%s'" -msgstr "kan inte ta bort citering av värdet \"%s\"" +msgstr "kan inte ta bort citering av värdet â€%sâ€" msgid "'GIT_AUTHOR_NAME' already given" -msgstr "\"GIT_AUTHOR_NAME\" har redan angivits" +msgstr "â€GIT_AUTHOR_NAME†har redan angivits" msgid "'GIT_AUTHOR_EMAIL' already given" -msgstr "\"GIT_AUTHOR_EMAIL\" har redan angivits" +msgstr "â€GIT_AUTHOR_EMAIL†har redan angivits" msgid "'GIT_AUTHOR_DATE' already given" -msgstr "\"GIT_AUTHOR_DATE\" har redan angivits" +msgstr "â€GIT_AUTHOR_DATE†har redan angivits" #, c-format msgid "unknown variable '%s'" -msgstr "okänd variabel \"%s\"" +msgstr "okänd variabel â€%sâ€" msgid "missing 'GIT_AUTHOR_NAME'" -msgstr "\"GIT_AUTHOR_NAME\" saknas" +msgstr "â€GIT_AUTHOR_NAME†saknas" msgid "missing 'GIT_AUTHOR_EMAIL'" -msgstr "\"GIT_AUTHOR_EMAIL\" saknas" +msgstr "â€GIT_AUTHOR_EMAIL†saknas" msgid "missing 'GIT_AUTHOR_DATE'" -msgstr "\"GIT_AUTHOR_DATE\" saknas" +msgstr "â€GIT_AUTHOR_DATE†saknas" #, c-format msgid "" @@ -19738,7 +19930,7 @@ msgstr "" " git rebase --continue\n" msgid "'prepare-commit-msg' hook failed" -msgstr "kroken \"prepare-commit-msg\" misslyckades" +msgstr "kroken â€prepare-commit-msg†misslyckades" msgid "" "Your name and email address were configured automatically based\n" @@ -19817,11 +20009,11 @@ msgstr "kunde inte tolka incheckningens författare" #, c-format msgid "unable to read commit message from '%s'" -msgstr "kunde inte läsa incheckningsmeddelande frÃ¥n \"%s\"" +msgstr "kunde inte läsa incheckningsmeddelande frÃ¥n â€%sâ€" #, c-format msgid "invalid author identity '%s'" -msgstr "ogiltig författar-identitet \"%s\"" +msgstr "ogiltig författar-identitet â€%sâ€" msgid "corrupt author: missing date information" msgstr "trasig författare: saknar datuminformation" @@ -19862,7 +20054,7 @@ msgstr "Det här är en kombination av %d incheckningar." #, c-format msgid "cannot write '%s'" -msgstr "kan inte skriva \"%s\"" +msgstr "kan inte skriva â€%sâ€" msgid "need a HEAD to fixup" msgstr "behöver en HEAD-incheckning att rätta" @@ -19881,7 +20073,7 @@ msgid "your index file is unmerged." msgstr "din indexfil har inte slagits ihop." msgid "cannot fixup root commit" -msgstr "kan inte göra \"fixup\" pÃ¥ rotincheckning" +msgstr "kan inte göra â€fixup†pÃ¥ rotincheckning" #, c-format msgid "commit %s is a merge but no -m option was given." @@ -19902,10 +20094,6 @@ msgid "%s: cannot parse parent commit %s" msgstr "%s: kan inte tolka föräldraincheckningen %s" #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "kunde inte byta namn pÃ¥ \"%s\" till \"%s\"" - -#, c-format msgid "could not revert %s... %s" msgstr "kunde inte Ã¥ngra %s... %s" @@ -19927,11 +20115,11 @@ msgstr "git %s: misslyckades uppdatera indexet" #, c-format msgid "'%s' is not a valid label" -msgstr "\"%s\" är inte en giltig etikett" +msgstr "â€%s†är inte en giltig etikett" #, c-format msgid "'%s' is not a valid refname" -msgstr "\"%s\" är inte ett giltigt referensnamn" +msgstr "â€%s†är inte ett giltigt referensnamn" #, c-format msgid "update-ref requires a fully qualified refname e.g. refs/heads/%s" @@ -19939,11 +20127,11 @@ msgstr "update-ref kräver ett fullständigt referensnamn, t.ex refs/heads/%s" #, c-format msgid "invalid command '%.*s'" -msgstr "ogiltigt kommando \"%.*s\"" +msgstr "ogiltigt kommando â€%.*sâ€" #, c-format msgid "%s does not accept arguments: '%s'" -msgstr "%s tar inte argument: \"%s\"" +msgstr "%s tar inte argument: â€%sâ€" #, c-format msgid "missing arguments for %s" @@ -19951,7 +20139,7 @@ msgstr "argument saknas för %s" #, c-format msgid "could not parse '%s'" -msgstr "kunde inte tolka \"%s\"" +msgstr "kunde inte tolka â€%sâ€" #, c-format msgid "invalid line %d: %.*s" @@ -19959,60 +20147,60 @@ msgstr "ogiltig rad %d: %.*s" #, c-format msgid "cannot '%s' without a previous commit" -msgstr "kan inte utföra \"%s\" utan en föregÃ¥ende incheckning" +msgstr "kan inte utföra â€%s†utan en föregÃ¥ende incheckning" msgid "cancelling a cherry picking in progress" -msgstr "avbryter pÃ¥gÃ¥ende \"cherry-pick\"" +msgstr "avbryter pÃ¥gÃ¥ende â€cherry-pickâ€" msgid "cancelling a revert in progress" -msgstr "avbryter pÃ¥gÃ¥ende \"revert\"" +msgstr "avbryter pÃ¥gÃ¥ende â€revertâ€" msgid "please fix this using 'git rebase --edit-todo'." -msgstr "rätta det med \"git rebase --edit-todo\"." +msgstr "rätta det med â€git rebase --edit-todoâ€." #, c-format msgid "unusable instruction sheet: '%s'" -msgstr "oanvändbart manus: \"%s\"" +msgstr "oanvändbart manus: â€%sâ€" msgid "no commits parsed." msgstr "inga incheckningar lästes." msgid "cannot cherry-pick during a revert." -msgstr "kan inte utföra \"cherry-pick\" under en \"revert\"." +msgstr "kan inte utföra â€cherry-pick†under en â€revertâ€." msgid "cannot revert during a cherry-pick." -msgstr "kan inte utföra \"revert\" under en \"cherry-pick\"." +msgstr "kan inte utföra â€revert†under en â€cherry-pickâ€." msgid "unusable squash-onto" msgstr "oanvändbar squash-onto" #, c-format msgid "malformed options sheet: '%s'" -msgstr "trasigt manus: \"%s\"" +msgstr "trasigt manus: â€%sâ€" msgid "empty commit set passed" msgstr "den angivna uppsättningen incheckningar är tom" msgid "revert is already in progress" -msgstr "en \"revert\" pÃ¥gÃ¥r redan" +msgstr "en â€revert†pÃ¥gÃ¥r redan" #, c-format msgid "try \"git revert (--continue | %s--abort | --quit)\"" -msgstr "testa \"git revert (--continue | %s--abort | --quit)\"" +msgstr "testa â€git revert (--continue | %s--abort | --quit)â€" msgid "cherry-pick is already in progress" -msgstr "en \"cherry-pick\" pÃ¥gÃ¥r redan" +msgstr "en â€cherry-pick†pÃ¥gÃ¥r redan" #, c-format msgid "try \"git cherry-pick (--continue | %s--abort | --quit)\"" -msgstr "testa \"git cherry-pick (--continue | %s--abort | --quit)\"" +msgstr "testa â€git cherry-pick (--continue | %s--abort | --quit)â€" #, c-format msgid "could not create sequencer directory '%s'" -msgstr "kunde inte skapa \"sequencer\"-katalogen \"%s\"" +msgstr "kunde inte skapa â€sequencerâ€-katalogen â€%sâ€" msgid "no cherry-pick or revert in progress" -msgstr "ingen \"cherry-pick\" eller \"revert\" pÃ¥gÃ¥r" +msgstr "ingen â€cherry-pick†eller â€revert†pÃ¥gÃ¥r" msgid "cannot resolve HEAD" msgstr "kan inte bestämma HEAD" @@ -20022,14 +20210,14 @@ msgstr "kan inte avbryta frÃ¥n en gren som ännu inte är född" #, c-format msgid "cannot read '%s': %s" -msgstr "kan inte läsa \"%s\": %s" +msgstr "kan inte läsa â€%sâ€: %s" msgid "unexpected end of file" msgstr "oväntat filslut" #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" -msgstr "sparad HEAD-fil frÃ¥n före \"cherry-pick\", \"%s\", är trasig" +msgstr "sparad HEAD-fil frÃ¥n före â€cherry-pickâ€, â€%sâ€, är trasig" msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!" msgstr "" @@ -20037,10 +20225,10 @@ msgstr "" "Spolar inte tillbaka, kontrollera HEAD!" msgid "no revert in progress" -msgstr "ingen \"revers\" pÃ¥gÃ¥r" +msgstr "ingen â€revert†pÃ¥gÃ¥r" msgid "no cherry-pick in progress" -msgstr "ingen \"cherry-pick\" pÃ¥gÃ¥r" +msgstr "ingen â€cherry-pick†pÃ¥gÃ¥r" msgid "failed to skip the commit" msgstr "kunde inte hoppa över incheckningen" @@ -20054,14 +20242,14 @@ msgid "" "try \"git %s --continue\"" msgstr "" "har du redan checkat in?\n" -"testa \"git %s --continue\"" +"testa â€git %s --continueâ€" msgid "cannot read HEAD" msgstr "kan inte läsa HEAD" #, c-format msgid "unable to copy '%s' to '%s'" -msgstr "kan inte kopiera in \"%s\" till \"%s\"" +msgstr "kan inte kopiera in â€%s†till â€%sâ€" #, c-format msgid "" @@ -20121,18 +20309,18 @@ msgid "" msgstr "" "körningen lyckades: %s\n" "men lämnade kvar ändringar i indexet och/eller arbetskatalogen.\n" -"Checka in eller utför \"stash\" pÃ¥ ändringarna och kör sedan\n" +"Checka in eller utför â€stash†pÃ¥ ändringarna och kör sedan\n" "\n" "\tgit rebase --continue\n" "\n" #, c-format msgid "illegal label name: '%.*s'" -msgstr "ogiltigt etikettnamn: \"%.*s\"" +msgstr "ogiltigt etikettnamn: â€%.*sâ€" #, c-format msgid "could not resolve '%s'" -msgstr "kunde inte upplösa \"%s\"" +msgstr "kunde inte upplösa â€%sâ€" msgid "writing fake root commit" msgstr "skriver fejkad rotincheckning" @@ -20145,22 +20333,22 @@ msgstr "kan inte slÃ¥ ihop utan en aktuell incheckning" #, c-format msgid "unable to parse '%.*s'" -msgstr "kan inte tolka \"%.*s\"" +msgstr "kan inte tolka â€%.*sâ€" #, c-format msgid "nothing to merge: '%.*s'" -msgstr "inget att slÃ¥ samman: \"%.*s\"" +msgstr "inget att slÃ¥ samman: â€%.*sâ€" msgid "octopus merge cannot be executed on top of a [new root]" -msgstr "\"octopus\"-sammanslagning kan inte köras ovanpÃ¥ en [ny rot]" +msgstr "â€octopusâ€-sammanslagning kan inte köras ovanpÃ¥ en [ny rot]" #, c-format msgid "could not get commit message of '%s'" -msgstr "kunde inte läsa incheckningsmeddelande för \"%s\"" +msgstr "kunde inte läsa incheckningsmeddelande för â€%sâ€" #, c-format msgid "could not even attempt to merge '%.*s'" -msgstr "kunde inte ens försöka slÃ¥ ihop \"%.*s\"" +msgstr "kunde inte ens försöka slÃ¥ ihop â€%.*sâ€" msgid "merge: Unable to write new index file" msgstr "sammanslagning: Kunde inte skriva ny indexfil" @@ -20168,7 +20356,7 @@ msgstr "sammanslagning: Kunde inte skriva ny indexfil" #, c-format msgid "" "another 'rebase' process appears to be running; '%s.lock' already exists" -msgstr "en annan \"rebase\"-process verkar vara aktiv; \"%s.lock\" finns redan" +msgstr "en annan â€rebaseâ€-process verkar vara aktiv; â€%s.lock†finns redan" #, c-format msgid "" @@ -20187,22 +20375,22 @@ msgstr "" "%s" msgid "Cannot autostash" -msgstr "Kan inte utföra \"autostash\"" +msgstr "Kan inte utföra â€autostashâ€" #, c-format msgid "Unexpected stash response: '%s'" -msgstr "Oväntat svar frÃ¥n stash: \"%s\"" +msgstr "Oväntat svar frÃ¥n stash: â€%sâ€" #, c-format msgid "Could not create directory for '%s'" -msgstr "Kunde inte skapa katalog för \"%s\"" +msgstr "Kunde inte skapa katalog för â€%sâ€" #, c-format msgid "Created autostash: %s\n" msgstr "Skapade autostash: %s\n" msgid "could not reset --hard" -msgstr "kunde inte utföra \"reset --hard\"" +msgstr "kunde inte utföra â€reset --hardâ€" #, c-format msgid "Applied autostash.\n" @@ -20220,7 +20408,7 @@ msgid "" msgstr "" "%s\n" "Dina ändringar är säkra i stashen.\n" -"Du kan när som helst använda \"git stash pop\" eller \"git stash drop\".\n" +"Du kan när som helst använda â€git stash pop†eller â€git stash dropâ€.\n" msgid "Applying autostash resulted in conflicts." msgstr "Tillämpning av autostash gav konflikter." @@ -20228,6 +20416,9 @@ msgstr "Tillämpning av autostash gav konflikter." msgid "Autostash exists; creating a new stash entry." msgstr "Autostash finns; skapar ny stash-post." +msgid "autostash reference is a symref" +msgstr "autostash-referensen är en symbolisk referens" + msgid "could not detach HEAD" msgstr "kunde inte koppla frÃ¥n HEAD" @@ -20260,14 +20451,14 @@ msgstr "" " git rebase --continue\n" #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "Ombaserar (%d/%d)%s" - -#, c-format msgid "Stopped at %s... %.*s\n" msgstr "Stoppade pÃ¥ %s... %.*s\n" #, c-format +msgid "Rebasing (%d/%d)%s" +msgstr "Ombaserar (%d/%d)%s" + +#, c-format msgid "unknown command %d" msgstr "okänt kommando %d" @@ -20275,7 +20466,7 @@ msgid "could not read orig-head" msgstr "kunde inte läsa orig-head" msgid "could not read 'onto'" -msgstr "kunde inte läsa \"onto\"" +msgstr "kunde inte läsa â€ontoâ€" #, c-format msgid "could not update HEAD to %s" @@ -20293,11 +20484,11 @@ msgstr "kan inte lägga till incheckning som inte finns" #, c-format msgid "invalid file: '%s'" -msgstr "ogiltig fil: \"%s\"" +msgstr "ogiltig fil: â€%sâ€" #, c-format msgid "invalid contents: '%s'" -msgstr "ogiltigt innehÃ¥ll: \"%s\"" +msgstr "ogiltigt innehÃ¥ll: â€%sâ€" msgid "" "\n" @@ -20306,11 +20497,11 @@ msgid "" msgstr "" "\n" "Du har ändringar i arbetskatalogen som inte checkats in. Checka in dem\n" -"först och kör sedan \"git rebase --continue\" igen." +"först och kör sedan â€git rebase --continue†igen." #, c-format msgid "could not write file: '%s'" -msgstr "kunde inte skriva fil: \"%s\"" +msgstr "kunde inte skriva fil: â€%sâ€" msgid "could not remove CHERRY_PICK_HEAD" msgstr "kunde inte ta bort CHERRY_PICK_HEAD" @@ -20320,7 +20511,7 @@ msgstr "kunde inte checka in köade ändringar." #, c-format msgid "%s: can't cherry-pick a %s" -msgstr "%s: kan inte göra \"cherry-pick\" pÃ¥ typen \"%s\"" +msgstr "%s: kan inte göra â€cherry-pick†pÃ¥ typen â€%sâ€" #, c-format msgid "%s: bad revision" @@ -20346,18 +20537,18 @@ msgid "nothing to do" msgstr "inget att göra" msgid "could not skip unnecessary pick commands" -msgstr "kunde inte hoppa över onödiga \"pick\"-kommandon" +msgstr "kunde inte hoppa över onödiga â€pickâ€-kommandon" msgid "the script was already rearranged." msgstr "skriptet har redan omordnats." #, c-format msgid "update-refs file at '%s' is invalid" -msgstr "update-refs-filen vid \"%s\" är ogiltig" +msgstr "update-refs-filen vid â€%s†är ogiltig" #, c-format msgid "'%s' is outside repository at '%s'" -msgstr "\"%s\" är utanför arkivet pÃ¥ \"%s\"" +msgstr "â€%s†är utanför arkivet pÃ¥ â€%sâ€" #, c-format msgid "" @@ -20365,7 +20556,7 @@ msgid "" "Use 'git <command> -- <path>...' to specify paths that do not exist locally." msgstr "" "%s: sökvägen finns inte i arbetskatalogen.\n" -"Använd \"git <kommando> -- <sökväg>..\" för att ange sökvägar som inte finns " +"Använd â€git <kommando> -- <sökväg>..†för att ange sökvägar som inte finns " "lokalt." #, c-format @@ -20374,14 +20565,14 @@ msgid "" "Use '--' to separate paths from revisions, like this:\n" "'git <command> [<revision>...] -- [<file>...]'" msgstr "" -"tvetydigt argument \"%s\": okänd revision eller sökväg inte i " +"tvetydigt argument â€%sâ€: okänd revision eller sökväg inte i " "arbetskatalogen.\n" -"Använd \"--\" för att skilja sökvägar frÃ¥n revisioner, sÃ¥ här:\n" -"\"git <kommando> [<revision>...] -- [<fil>...]\"" +"Använd â€--†för att skilja sökvägar frÃ¥n revisioner, sÃ¥ här:\n" +"â€git <kommando> [<revision>...] -- [<fil>...]â€" #, c-format msgid "option '%s' must come before non-option arguments" -msgstr "flaggan \"%s\" mÃ¥ste anges före argument som inte är flaggor" +msgstr "flaggan â€%s†mÃ¥ste anges före argument som inte är flaggor" #, c-format msgid "" @@ -20389,9 +20580,9 @@ msgid "" "Use '--' to separate paths from revisions, like this:\n" "'git <command> [<revision>...] -- [<file>...]'" msgstr "" -"tvetydigt argument \"%s\": bÃ¥de revision och filnamn\n" -"Använd \"--\" för att skilja sökvägar frÃ¥n revisioner, sÃ¥ här:\n" -"\"git <kommando> [<revision>...] -- [<fil>...]\"" +"tvetydigt argument â€%sâ€: bÃ¥de revision och filnamn\n" +"Använd â€--†för att skilja sökvägar frÃ¥n revisioner, sÃ¥ här:\n" +"â€git <kommando> [<revision>...] -- [<fil>...]â€" msgid "unable to set up work tree using invalid config" msgstr "kan inte skapa arbetskatalog med felaktig konfiguration" @@ -20412,11 +20603,11 @@ msgstr[1] "arkivversionen är 0, men utökningar som bara finns i v1 upptäcktes #, c-format msgid "error opening '%s'" -msgstr "fel vid öppning av \"%s\"" +msgstr "fel vid öppning av â€%sâ€" #, c-format msgid "too large to be a .git file: '%s'" -msgstr "för stor för att vara en .git-fil: \"%s\"" +msgstr "för stor för att vara en .git-fil: â€%sâ€" #, c-format msgid "error reading %s" @@ -20436,29 +20627,29 @@ msgstr "inte ett git-arkiv: %s" #, c-format msgid "'$%s' too big" -msgstr "\"$%s\" för stor" +msgstr "â€$%s†för stor" #, c-format msgid "not a git repository: '%s'" -msgstr "inte ett git-arkiv: \"%s\"" +msgstr "inte ett git-arkiv: â€%sâ€" #, c-format msgid "cannot chdir to '%s'" -msgstr "kan inte byta katalog (chdir) till \"%s\"" +msgstr "kan inte byta katalog (chdir) till â€%sâ€" msgid "cannot come back to cwd" msgstr "kan inte gÃ¥ tillbaka till arbetskatalogen (cwd)" #, c-format msgid "failed to stat '%*s%s%s'" -msgstr "misslyckades ta status pÃ¥ \"%*ss%s%s\"" +msgstr "misslyckades ta status pÃ¥ â€%*ss%s%sâ€" msgid "Unable to read current working directory" msgstr "Kan inte läsa aktuell arbetskatalog" #, c-format msgid "cannot change to '%s'" -msgstr "kan inte byta till \"%s\"" +msgstr "kan inte byta till â€%sâ€" #, c-format msgid "not a git repository (or any of the parent directories): %s" @@ -20480,14 +20671,14 @@ msgid "" "\n" "\tgit config --global --add safe.directory %s" msgstr "" -"upptäckte tveksamt ägarskap i arkivet i \"%s\"\n" +"upptäckte tveksamt ägarskap i arkivet i â€%sâ€\n" "%sFör att lägga till ett undantag för denna katalog, kör:\n" "\n" "\tgit config --global --add safe.directory %s" #, c-format msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')" -msgstr "kan inte använda naket arkiv \"%s\" (safe.bareRepository är \"%s\")" +msgstr "kan inte använda naket arkiv â€%s†(safe.bareRepository är â€%sâ€)" #, c-format msgid "" @@ -20498,30 +20689,30 @@ msgstr "" "Ägaren av filerna mÃ¥ste alltid ha läs- och skrivbehörighet." msgid "fork failed" -msgstr "\"fork\" misslyckades" +msgstr "â€fork†misslyckades" msgid "setsid failed" -msgstr "\"setsid\" misslyckades" +msgstr "â€setsid†misslyckades" #, c-format msgid "cannot stat template '%s'" -msgstr "kan inte ta status pÃ¥ mallen \"%s\"" +msgstr "kan inte ta status pÃ¥ mallen â€%sâ€" #, c-format msgid "cannot opendir '%s'" -msgstr "kan inte öppna katalogen (opendir) \"%s\"" +msgstr "kan inte öppna katalogen (opendir) â€%sâ€" #, c-format msgid "cannot readlink '%s'" -msgstr "kan inte läsa länk (readlink) \"%s\"" +msgstr "kan inte läsa länk (readlink) â€%sâ€" #, c-format msgid "cannot symlink '%s' '%s'" -msgstr "kan inte skapa symbolisk länk \"%s\" \"%s\"" +msgstr "kan inte skapa symbolisk länk â€%s†â€%sâ€" #, c-format msgid "cannot copy '%s' to '%s'" -msgstr "kan inte kopiera \"%s\" till \"%s\"" +msgstr "kan inte kopiera â€%s†till â€%sâ€" #, c-format msgid "ignoring template %s" @@ -20533,11 +20724,15 @@ msgstr "mallarna hittades inte i %s" #, c-format msgid "not copying templates from '%s': %s" -msgstr "kopierade inte mallar frÃ¥n \"%s\": %s" +msgstr "kopierade inte mallar frÃ¥n â€%sâ€: %s" #, c-format msgid "invalid initial branch name: '%s'" -msgstr "ogiltigt namn pÃ¥ första gren: \"%s\"" +msgstr "ogiltigt namn pÃ¥ första gren: â€%sâ€" + +#, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "re-init: ignorerade --initial-branch=%s" #, c-format msgid "unable to handle file type %d" @@ -20550,15 +20745,15 @@ msgstr "kan inte flytta %s till %s" msgid "attempt to reinitialize repository with different hash" msgstr "försöker initiera arkivet pÃ¥ nytt med annan hash" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "försöker initiera arkivet pÃ¥ nytt med annat referenslagringsformat" + #, c-format msgid "%s already exists" msgstr "%s finns redan" #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "re-init: ignorerade --initial-branch=%s" - -#, c-format msgid "Reinitialized existing shared Git repository in %s%s\n" msgstr "Ominitierade befintligt delat Git-arkiv i %s%s\n" @@ -20634,7 +20829,7 @@ msgstr "negativa värden är inte tillÃ¥tna för submodule.fetchJobs" #, c-format msgid "ignoring '%s' which may be interpreted as a command-line option: %s" -msgstr "ignorerar \"%s\" som kan tolkas som en kommandoradsflagga: %s" +msgstr "ignorerar â€%s†som kan tolkas som en kommandoradsflagga: %s" #, c-format msgid "Could not update .gitmodules entry %s" @@ -20658,11 +20853,11 @@ msgstr "misslyckades köa uppdaterad .gitmodules" #, c-format msgid "in unpopulated submodule '%s'" -msgstr "i ej utcheckad undermodul \"%s\"" +msgstr "i ej utcheckad undermodul â€%sâ€" #, c-format msgid "Pathspec '%s' is in submodule '%.*s'" -msgstr "Sökvägsangivelsen \"%s\" är i undermodulen \"%.*s\"" +msgstr "Sökvägsangivelsen â€%s†är i undermodulen â€%.*sâ€" #, c-format msgid "bad --ignore-submodules argument: %s" @@ -20673,32 +20868,32 @@ msgid "" "Submodule in commit %s at path: '%s' collides with a submodule named the " "same. Skipping it." msgstr "" -"Undermodulen i incheckning %s pÃ¥ sökvägen: \"%s\" krockar med en undermodul " +"Undermodulen i incheckning %s pÃ¥ sökvägen: â€%s†krockar med en undermodul " "med samma namn. Hoppar över den." #, c-format msgid "submodule entry '%s' (%s) is a %s, not a commit" -msgstr "undermodulposten \"%s\" (%s) är en %s, inte en incheckning" +msgstr "undermodulposten â€%s†(%s) är en %s, inte en incheckning" #, c-format msgid "" "Could not run 'git rev-list <commits> --not --remotes -n 1' command in " "submodule %s" msgstr "" -"kunde inte köra \"git rev-list <incheckningar> --not --remotes -n 1\" i " -"undermodulen \"%s\"" +"kunde inte köra â€git rev-list <incheckningar> --not --remotes -n 1†i " +"undermodulen â€%sâ€" #, c-format msgid "process for submodule '%s' failed" -msgstr "process för undermodulen \"%s\" misslyckades" +msgstr "process för undermodulen â€%s†misslyckades" #, c-format msgid "Pushing submodule '%s'\n" -msgstr "Sänder undermodulen \"%s\"\n" +msgstr "Sänder undermodulen â€%sâ€\n" #, c-format msgid "Unable to push submodule '%s'\n" -msgstr "Kunde inte sända undermodulen \"%s\"\n" +msgstr "Kunde inte sända undermodulen â€%sâ€\n" #, c-format msgid "Fetching submodule %s%s\n" @@ -20706,11 +20901,11 @@ msgstr "Hämtar undermodulen %s%s\n" #, c-format msgid "Could not access submodule '%s'\n" -msgstr "Kunde inte komma Ã¥t undermodulen \"%s\"\n" +msgstr "Kunde inte komma Ã¥t undermodulen â€%sâ€\n" #, c-format msgid "Could not access submodule '%s' at commit %s\n" -msgstr "Kunde inte komma Ã¥t undermodulen \"%s\" vid incheckningen %s\n" +msgstr "Kunde inte komma Ã¥t undermodulen â€%s†vid incheckningen %s\n" #, c-format msgid "Fetching submodule %s%s at commit %s\n" @@ -20726,61 +20921,61 @@ msgstr "" #, c-format msgid "'%s' not recognized as a git repository" -msgstr "\"%s\" känns inte igen som ett git-arkiv" +msgstr "â€%s†känns inte igen som ett git-arkiv" #, c-format msgid "Could not run 'git status --porcelain=2' in submodule %s" -msgstr "Kunde inte köra \"git status --porcelain=2\" i undermodulen \"%s\"" +msgstr "Kunde inte köra â€git status --porcelain=2†i undermodulen â€%sâ€" #, c-format msgid "'git status --porcelain=2' failed in submodule %s" -msgstr "\"git status --porcelain=2\" misslyckades i undermodulen \"%s\"" +msgstr "â€git status --porcelain=2†misslyckades i undermodulen â€%sâ€" #, c-format msgid "could not start 'git status' in submodule '%s'" -msgstr "kunde inte starta \"git status\" i undermodulen \"%s\"" +msgstr "kunde inte starta â€git status†i undermodulen â€%sâ€" #, c-format msgid "could not run 'git status' in submodule '%s'" -msgstr "kunde inte köra \"git status\" i undermodulen \"%s\"" +msgstr "kunde inte köra â€git status†i undermodulen â€%sâ€" #, c-format msgid "Could not unset core.worktree setting in submodule '%s'" -msgstr "Kunde inte ta bort inställningen core.worktree i undermodulen \"%s\"" +msgstr "Kunde inte ta bort inställningen core.worktree i undermodulen â€%sâ€" #, c-format msgid "could not recurse into submodule '%s'" -msgstr "kunde inte rekursera in i undermodulen \"%s\"" +msgstr "kunde inte rekursera in i undermodulen â€%sâ€" msgid "could not reset submodule index" msgstr "kunde inte Ã¥terställa indexet i undermodul" #, c-format msgid "submodule '%s' has dirty index" -msgstr "undermodulen \"%s\" har ett smutsigt index" +msgstr "undermodulen â€%s†har ett smutsigt index" #, c-format msgid "Submodule '%s' could not be updated." -msgstr "Undermoduler \"%s\" kunde inte uppdateras." +msgstr "Undermoduler â€%s†kunde inte uppdateras." #, c-format msgid "submodule git dir '%s' is inside git dir '%.*s'" -msgstr "undermodul-gitkatalogen \"%s\" är inuti gitkatalogen \"%.*s\"" +msgstr "undermodul-gitkatalogen â€%s†är inuti gitkatalogen â€%.*sâ€" #, c-format msgid "" "relocate_gitdir for submodule '%s' with more than one worktree not supported" msgstr "" -"relocate_gitdir för undermodulen \"%s\", som har mer än en arbetskatalog, " +"relocate_gitdir för undermodulen â€%sâ€, som har mer än en arbetskatalog, " "stöds ej" #, c-format msgid "could not lookup name for submodule '%s'" -msgstr "kunde inte slÃ¥ upp namnet för undermodulen \"%s\"" +msgstr "kunde inte slÃ¥ upp namnet för undermodulen â€%sâ€" #, c-format msgid "refusing to move '%s' into an existing git dir" -msgstr "vägrar flytta \"%s\" till en befintlig gitkatalog" +msgstr "vägrar flytta â€%s†till en befintlig gitkatalog" #, c-format msgid "" @@ -20788,9 +20983,9 @@ msgid "" "'%s' to\n" "'%s'\n" msgstr "" -"Migrerar git-katalogen för \"%s%s\" frÃ¥n\n" -"\"%s\" till\n" -"\"%s\"\n" +"Migrerar git-katalogen för â€%s%s†frÃ¥n\n" +"â€%s†till\n" +"â€%sâ€\n" msgid "could not start ls-files in .." msgstr "kunde inte starta ls-files i .." @@ -20801,14 +20996,14 @@ msgstr "ls-tree returnerade en oväntad returkod %d" #, c-format msgid "failed to lstat '%s'" -msgstr "misslyckades ta status (lstat) pÃ¥ \"%s\"" +msgstr "misslyckades ta status (lstat) pÃ¥ â€%sâ€" msgid "no remote configured to get bundle URIs from" msgstr "ingen fjärr att hämta bunt-URI:er frÃ¥n inställd" #, c-format msgid "remote '%s' has no configured URL" -msgstr "fjärren \"%s\" har ingen URL konfigurerad" +msgstr "fjärren â€%s†har ingen URL konfigurerad" msgid "could not get the bundle-uri list" msgstr "kunde inte hämta bundle-uri-listan" @@ -20822,12 +21017,6 @@ msgstr "töm cacheträdet före varje iteration" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "antal poster i cacheträdet att ogiltigförklara (förval är 0)" -msgid "unhandled options" -msgstr "flaggor som inte hanterats" - -msgid "error preparing revisions" -msgstr "fel när revisioner skulle förberedas" - #, c-format msgid "commit %s is not marked reachable" msgstr "incheckning %s är inte märkt nÃ¥bar" @@ -20899,19 +21088,19 @@ msgstr "igenkänningstecken för kommando att sända till servern" #, c-format msgid "running trailer command '%s' failed" -msgstr "misslyckades utföra släpradskommandot \"%s\"" +msgstr "misslyckades utföra släpradskommandot â€%sâ€" #, c-format msgid "unknown value '%s' for key '%s'" -msgstr "okänt värde \"%s\" för nyckeln \"%s\"" +msgstr "okänt värde â€%s†för nyckeln â€%sâ€" #, c-format msgid "empty trailer token in trailer '%.*s'" -msgstr "tom släpradssymbol i släpraden \"%.*s\"" +msgstr "tom släpradssymbol i släpraden â€%.*sâ€" #, c-format msgid "could not read input file '%s'" -msgstr "kunde inte läsa indatafilen \"%s\"" +msgstr "kunde inte läsa indatafilen â€%sâ€" #, c-format msgid "could not stat %s" @@ -20937,7 +21126,7 @@ msgstr "komplett skrivning till fjärrhjälpare misslyckades" #, c-format msgid "unable to find remote helper for '%s'" -msgstr "kan inte hitta fjärrhjälpare för \"%s\"" +msgstr "kan inte hitta fjärrhjälpare för â€%sâ€" msgid "can't dup helper output fd" msgstr "kunde inte duplicera utdata-filhandtag" @@ -20957,7 +21146,7 @@ msgstr "" #, c-format msgid "%s unexpectedly said: '%s'" -msgstr "%s sade oväntat: \"%s\"" +msgstr "%s sade oväntat: â€%sâ€" #, c-format msgid "%s also locked %s" @@ -20983,9 +21172,6 @@ msgstr "protkollet stöder inte att sätta sökväg till fjärrtjänst" msgid "invalid remote service path" msgstr "felaktig sökväg till fjärrtjänst" -msgid "operation not supported by protocol" -msgstr "funktionen stöds inte av protokollet" - #, c-format msgid "can't connect to subservice %s" msgstr "kan inte ansluta till undertjänsten %s" @@ -20994,11 +21180,11 @@ msgid "--negotiate-only requires protocol v2" msgstr "--negotiate-only kräver protokoll v2" msgid "'option' without a matching 'ok/error' directive" -msgstr "\"option\" utan mostsvarande \"ok/error\"-direktiv" +msgstr "â€option†utan mostsvarande â€ok/errorâ€-direktiv" #, c-format msgid "expected ok/error, helper said '%s'" -msgstr "förväntade ok/error, hjälpprogrammet svarade \"%s\"" +msgstr "förväntade ok/error, hjälpprogrammet svarade â€%sâ€" #, c-format msgid "helper reported unexpected status of %s" @@ -21026,14 +21212,14 @@ msgstr "hjälparen %s stöder inte --%s" #, c-format msgid "helper %s does not support 'push-option'" -msgstr "hjälparen %s stöder inte \"push-option\"" +msgstr "hjälparen %s stöder inte â€push-optionâ€" msgid "remote-helper doesn't support push; refspec needed" msgstr "fjärrhjälparen stöder inte push; referensspecifikation krävs" #, c-format msgid "helper %s does not support 'force'" -msgstr "hjälparen %s stöder inte \"force\"" +msgstr "hjälparen %s stöder inte â€forceâ€" msgid "couldn't run fast-export" msgstr "kunde inte köra fast-export" @@ -21051,7 +21237,7 @@ msgstr "" #, c-format msgid "unsupported object format '%s'" -msgstr "objektformatet \"%s\" stöds ej" +msgstr "objektformatet â€%s†stöds ej" #, c-format msgid "malformed response in ref list: %s" @@ -21090,18 +21276,18 @@ msgstr "kan inte skapa trÃ¥d för kopiering av data" #, c-format msgid "Would set upstream of '%s' to '%s' of '%s'\n" -msgstr "Skulle sätta uppströms för \"%s\" till \"%s\" frÃ¥n \"%s\"\n" +msgstr "Skulle sätta uppströms för â€%s†till â€%s†frÃ¥n â€%sâ€\n" #, c-format msgid "could not read bundle '%s'" -msgstr "kunde inte läsa bunten \"%s\"" +msgstr "kunde inte läsa bunten â€%sâ€" #, c-format msgid "transport: invalid depth option '%s'" -msgstr "transport: ogiltig flagga för depth: \"%s\"" +msgstr "transport: ogiltig flagga för depth: â€%sâ€" msgid "see protocol.version in 'git help config' for more details" -msgstr "se protocol.version i \"git help config\" för mer information" +msgstr "se protocol.version i â€git help config†för mer information" msgid "server options require protocol version 2 or later" msgstr "serverflaggor kräver protokollversion 2 eller senare" @@ -21116,12 +21302,8 @@ msgid "support for protocol v2 not implemented yet" msgstr "stöd för protokoll v2 ännu ej implementerat" #, c-format -msgid "unknown value for config '%s': %s" -msgstr "okänt värde för inställningen \"%s\": %s" - -#, c-format msgid "transport '%s' not allowed" -msgstr "transporten \"%s\" tillÃ¥ts inte" +msgstr "transporten â€%s†tillÃ¥ts inte" msgid "git-over-rsync is no longer supported" msgstr "git-over-rsync stöds inte längre" @@ -21172,6 +21354,9 @@ msgstr "bundle-uri-funktionen stöds inte av protokollet" msgid "could not retrieve server-advertised bundle-uri list" msgstr "kunde inte hämta bundle-uri-listan som servern annonserade" +msgid "operation not supported by protocol" +msgstr "funktionen stöds inte av protokollet" + msgid "too-short tree object" msgstr "trädobjekt för kort" @@ -21190,7 +21375,7 @@ msgid "" "%%sPlease commit your changes or stash them before you switch branches." msgstr "" "Dina lokala ändringar av följande filer skulle skrivas över av utcheckning:\n" -"%%sChecka in dina ändringar eller använd \"stash\" innan du byter gren." +"%%sChecka in dina ändringar eller använd â€stash†innan du byter gren." #, c-format msgid "" @@ -21207,7 +21392,7 @@ msgid "" msgstr "" "Dina lokala ändringar av följande filer skulle skrivas över av " "sammanslagning:\n" -"%%sChecka in dina ändringar eller använd \"stash\" innan du byter gren." +"%%sChecka in dina ändringar eller använd â€stash†innan du byter gren." #, c-format msgid "" @@ -21223,15 +21408,15 @@ 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 "" -"Dina lokala ändringar av följande filer skulle skrivas över av \"%s\":\n" -"%%sChecka in dina ändringar eller använd \"stash\" innan du \"%s\"." +"Dina lokala ändringar av följande filer skulle skrivas över av â€%sâ€:\n" +"%%sChecka in dina ändringar eller använd â€stash†innan du â€%sâ€." #, c-format msgid "" "Your local changes to the following files would be overwritten by %s:\n" "%%s" msgstr "" -"Dina lokala ändringar av följande filer skulle skrivas över av \"%s\":\n" +"Dina lokala ändringar av följande filer skulle skrivas över av â€%sâ€:\n" "%%s" #, c-format @@ -21290,15 +21475,15 @@ msgid "" "The following untracked working tree files would be removed by %s:\n" "%%sPlease move or remove them before you %s." msgstr "" -"Följande ospÃ¥rade filer i arbetskatalogen skulle tas bort av \"%s\":\n" -"%%sFlytta eller ta bort dem innan du \"%s\"." +"Följande ospÃ¥rade filer i arbetskatalogen skulle tas bort av â€%sâ€:\n" +"%%sFlytta eller ta bort dem innan du â€%sâ€." #, c-format msgid "" "The following untracked working tree files would be removed by %s:\n" "%%s" msgstr "" -"Följande ospÃ¥rade filer i arbetskatalogen skulle tas bort av \"%s\":\n" +"Följande ospÃ¥rade filer i arbetskatalogen skulle tas bort av â€%sâ€:\n" "%%s" #, c-format @@ -21344,20 +21529,20 @@ msgid "" "The following untracked working tree files would be overwritten by %s:\n" "%%sPlease move or remove them before you %s." msgstr "" -"Följande ospÃ¥rade filer i arbetskatalogen skulle skrivas över av \"%s\":\n" -"%%sFlytta eller ta bort dem innan du \"%s\"." +"Följande ospÃ¥rade filer i arbetskatalogen skulle skrivas över av â€%sâ€:\n" +"%%sFlytta eller ta bort dem innan du â€%sâ€." #, c-format msgid "" "The following untracked working tree files would be overwritten by %s:\n" "%%s" msgstr "" -"Följande ospÃ¥rade filer i arbetskatalogen skulle skrivas över av \"%s\":\n" +"Följande ospÃ¥rade filer i arbetskatalogen skulle skrivas över av â€%sâ€:\n" "%%s" #, c-format msgid "Entry '%s' overlaps with '%s'. Cannot bind." -msgstr "Posten \"%s\" överlappar \"%s\". Kan inte binda." +msgstr "Posten â€%s†överlappar â€%sâ€. Kan inte binda." #, c-format msgid "" @@ -21404,7 +21589,7 @@ msgid "" "After fixing the above paths, you may want to run `git sparse-checkout " "reapply`.\n" msgstr "" -"Du bör köra \"git sparse-checkout reapply\" efter att ha fixat sökvägarna " +"Du bör köra â€git sparse-checkout reapply†efter att ha fixat sökvägarna " "ovan.\n" msgid "Updating files" @@ -21427,20 +21612,20 @@ msgid "worktree and untracked commit have duplicate entries: %s" msgstr "arbetskatalog och ospÃ¥rad incheckning har dublettposter: %s" msgid "expected flush after fetch arguments" -msgstr "förväntade \"flush\" efter \"fetch\"-argument" +msgstr "förväntade â€flush†efter â€fetchâ€-argument" msgid "invalid URL scheme name or missing '://' suffix" -msgstr "ogiltig URL-schemanamn eller saknat \"://\"-suffix" +msgstr "ogiltig URL-schemanamn eller saknat â€://â€-suffix" #, c-format msgid "invalid %XX escape sequence" msgstr "ogiltig %XX-teckensekvens" msgid "missing host and scheme is not 'file:'" -msgstr "värd saknas och schemat är inte \"file:\"" +msgstr "värd saknas och schemat är inte â€file:â€" msgid "a 'file:' URL may not have a port number" -msgstr "en \"file:\"-URL kan inte innehÃ¥lla portnummer" +msgstr "en â€file:â€-URL kan inte innehÃ¥lla portnummer" msgid "invalid characters in host name" msgstr "ogiltiga tecken i värdnamnet" @@ -21449,7 +21634,7 @@ msgid "invalid port number" msgstr "felaktigt portnummer" msgid "invalid '..' path segment" -msgstr "felaktigt \"..\"-sökvägssegment" +msgstr "felaktigt â€..â€-sökvägssegment" msgid "usage: " msgstr "användning: " @@ -21468,19 +21653,19 @@ msgstr "Hämtar objekt" #, c-format msgid "'%s' at main working tree is not the repository directory" -msgstr "\"%s\" i huvudarbetskatalogen är inte arkivkatalogen" +msgstr "â€%s†i huvudarbetskatalogen är inte arkivkatalogen" #, c-format msgid "'%s' file does not contain absolute path to the working tree location" -msgstr "filen \"%s\" innehÃ¥ller inte absolut sökväg till arbetskatalogen" +msgstr "filen â€%s†innehÃ¥ller inte absolut sökväg till arbetskatalogen" #, c-format msgid "'%s' is not a .git file, error code %d" -msgstr "\"%s\" är inte en .git-fil, felkod %d" +msgstr "â€%s†är inte en .git-fil, felkod %d" #, c-format msgid "'%s' does not point back to '%s'" -msgstr "\"%s\" pekar inte tillbaka till \"%s\"" +msgstr "â€%s†pekar inte tillbaka till â€%sâ€" msgid "not a directory" msgstr "inte en katalog" @@ -21534,57 +21719,60 @@ msgstr "gitdir-filen pekar pÃ¥ en ickeexisterande plats" #, c-format msgid "unable to set %s in '%s'" -msgstr "kan inte sätta %s i \"%s\"" +msgstr "kan inte sätta %s i â€%sâ€" #, c-format msgid "unable to unset %s in '%s'" -msgstr "kan inte slÃ¥ av %s i \"%s\"" +msgstr "kan inte slÃ¥ av %s i â€%sâ€" msgid "failed to set extensions.worktreeConfig setting" msgstr "misslyckades ändra inställningen extensions.worktreeConfig" #, c-format msgid "could not setenv '%s'" -msgstr "kunde inte lagra miljövariabeln \"%s\"" +msgstr "kunde inte lagra miljövariabeln â€%sâ€" #, c-format msgid "unable to create '%s'" -msgstr "kunde inte skapa \"%s\"" +msgstr "kunde inte skapa â€%sâ€" #, c-format msgid "could not open '%s' for reading and writing" -msgstr "kunde inte öppna \"%s\" för läsning och skrivning" +msgstr "kunde inte öppna â€%s†för läsning och skrivning" #, c-format msgid "unable to access '%s'" -msgstr "kan inte komma Ã¥t \"%s\"" +msgstr "kan inte komma Ã¥t â€%sâ€" msgid "unable to get current working directory" msgstr "kan inte hämta aktuell arbetskatalog" +msgid "unable to get random bytes" +msgstr "kunde inte hämta slumpdata" + msgid "Unmerged paths:" msgstr "Ej sammanslagna sökvägar:" msgid " (use \"git restore --staged <file>...\" to unstage)" -msgstr " (använd \"git restore --staged <fil>...\" för att ta bort frÃ¥n kö)" +msgstr " (använd â€git restore --staged <fil>...†för att ta bort frÃ¥n kö)" #, c-format msgid " (use \"git restore --source=%s --staged <file>...\" to unstage)" msgstr "" -" (använd \"git restore --source=%s --staged <fil>...\" för att ta bort frÃ¥n " +" (använd â€git restore --source=%s --staged <fil>...†för att ta bort frÃ¥n " "kö)" msgid " (use \"git rm --cached <file>...\" to unstage)" -msgstr " (använd \"git rm --cached <fil>...\" för att ta bort frÃ¥n kö)" +msgstr " (använd â€git rm --cached <fil>...†för att ta bort frÃ¥n kö)" msgid " (use \"git add <file>...\" to mark resolution)" -msgstr " (använd \"git add <fil>...\" för att ange lösning)" +msgstr " (använd â€git add <fil>...†för att ange lösning)" msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)" -msgstr " (använd \"git add/rm <fil>...\" som lämpligt för att ange lösning)" +msgstr " (använd â€git add/rm <fil>...†som lämpligt för att ange lösning)" msgid " (use \"git rm <file>...\" to mark resolution)" -msgstr " (använd \"git rm <fil>...\" för att ange lösning)" +msgstr " (använd â€git rm <fil>...†för att ange lösning)" msgid "Changes to be committed:" msgstr "Ändringar att checka in:" @@ -21593,17 +21781,16 @@ msgid "Changes not staged for commit:" msgstr "Ändringar ej i incheckningskön:" msgid " (use \"git add <file>...\" to update what will be committed)" -msgstr "" -" (använd \"git add <fil>...\" för att uppdatera vad som ska checkas in)" +msgstr " (använd â€git add <fil>...†för att uppdatera vad som ska checkas in)" msgid " (use \"git add/rm <file>...\" to update what will be committed)" msgstr "" -" (använd \"git add/rm <fil>...\" för att uppdatera vad som ska checkas in)" +" (använd â€git add/rm <fil>...†för att uppdatera vad som ska checkas in)" msgid "" " (use \"git restore <file>...\" to discard changes in working directory)" msgstr "" -" (använd \"git restore <fil>...\" för att förkasta ändringar i " +" (använd â€git restore <fil>...†för att förkasta ändringar i " "arbetskatalogen)" msgid " (commit or discard the untracked or modified content in submodules)" @@ -21612,7 +21799,7 @@ msgstr "" #, c-format msgid " (use \"git %s <file>...\" to include in what will be committed)" -msgstr " (använd \"git %s <fil>...\" för att ta med i det som ska checkas in)" +msgstr " (använd â€git %s <fil>...†för att ta med i det som ska checkas in)" msgid "both deleted:" msgstr "borttaget av bägge:" @@ -21695,43 +21882,43 @@ msgid "" msgstr "" "\n" "Det tog %.2f sekunder att räkna före/bakom-värden.\n" -"Du kan använda \"--no-ahead-behind\" för undvika detta.\n" +"Du kan använda â€--no-ahead-behind†för undvika detta.\n" msgid "You have unmerged paths." msgstr "Du har ej sammanslagna sökvägar." msgid " (fix conflicts and run \"git commit\")" -msgstr " (rätta konflikter och kör \"git commit\")" +msgstr " (rätta konflikter och kör â€git commitâ€)" msgid " (use \"git merge --abort\" to abort the merge)" -msgstr " (använd \"git merge --abort\" för att avbryta sammanslagningen)" +msgstr " (använd â€git merge --abort†för att avbryta sammanslagningen)" msgid "All conflicts fixed but you are still merging." msgstr "Alla konflikter har rättats men du är fortfarande i en sammanslagning." msgid " (use \"git commit\" to conclude merge)" -msgstr " (använd \"git commit\" för att slutföra sammanslagningen)" +msgstr " (använd â€git commit†för att slutföra sammanslagningen)" msgid "You are in the middle of an am session." -msgstr "Du är i mitten av en körning av \"git am\"." +msgstr "Du är i mitten av en körning av â€git amâ€." msgid "The current patch is empty." msgstr "Aktuell patch är tom." msgid " (fix conflicts and then run \"git am --continue\")" -msgstr " (rätta konflikter och kör sedan \"git am --continue\")" +msgstr " (rätta konflikter och kör sedan â€git am --continueâ€)" msgid " (use \"git am --skip\" to skip this patch)" -msgstr " (använd \"git am --skip\" för att hoppa över patchen)" +msgstr " (använd â€git am --skip†för att hoppa över patchen)" msgid "" " (use \"git am --allow-empty\" to record this patch as an empty commit)" msgstr "" -" (använd \"git am --allow-empty\" för att registrera patchen som en tom " +" (använd â€git am --allow-empty†för att registrera patchen som en tom " "incheckning)" msgid " (use \"git am --abort\" to restore the original branch)" -msgstr " (använd \"git am --abort\" för att Ã¥terställa ursprungsgrenen)" +msgstr " (använd â€git am --abort†för att Ã¥terställa ursprungsgrenen)" msgid "git-rebase-todo is missing." msgstr "git-rebase-todo saknas." @@ -21759,79 +21946,79 @@ msgstr[0] "Nästa kommando att utföra (%<PRIuMAX> kommando Ã¥terstÃ¥r):" msgstr[1] "Följande kommandon att utföra (%<PRIuMAX> kommandon Ã¥terstÃ¥r):" msgid " (use \"git rebase --edit-todo\" to view and edit)" -msgstr " (använd \"git rebase --edit-todo\" för att visa och redigera)" +msgstr " (använd â€git rebase --edit-todo†för att visa och redigera)" #, c-format msgid "You are currently rebasing branch '%s' on '%s'." -msgstr "Du hÃ¥ller pÃ¥ att ombasera grenen \"%s\" ovanpÃ¥ \"%s\"." +msgstr "Du hÃ¥ller pÃ¥ att ombasera grenen â€%s†ovanpÃ¥ â€%sâ€." msgid "You are currently rebasing." msgstr "Du hÃ¥ller pÃ¥ med en ombasering." msgid " (fix conflicts and then run \"git rebase --continue\")" -msgstr " (rätta konflikter och kör sedan \"git rebase --continue\")" +msgstr " (rätta konflikter och kör sedan â€git rebase --continueâ€)" msgid " (use \"git rebase --skip\" to skip this patch)" -msgstr " (använd \"git rebase --skip\" för att hoppa över patchen)" +msgstr " (använd â€git rebase --skip†för att hoppa över patchen)" msgid " (use \"git rebase --abort\" to check out the original branch)" -msgstr " (använd \"git rebase --abort\" för att checka ut ursprungsgrenen)" +msgstr " (använd â€git rebase --abort†för att checka ut ursprungsgrenen)" msgid " (all conflicts fixed: run \"git rebase --continue\")" -msgstr " (alla konflikter rättade: kör \"git rebase --continue\")" +msgstr " (alla konflikter rättade: kör â€git rebase --continueâ€)" #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." msgstr "" -"Du hÃ¥ller pÃ¥ att dela upp en incheckning medan du ombaserar grenen \"%s\" " -"ovanpÃ¥ \"%s\"." +"Du hÃ¥ller pÃ¥ att dela upp en incheckning medan du ombaserar grenen â€%s†" +"ovanpÃ¥ â€%sâ€." msgid "You are currently splitting a commit during a rebase." msgstr "Du hÃ¥ller pÃ¥ att dela upp en incheckning i en ombasering." msgid " (Once your working directory is clean, run \"git rebase --continue\")" -msgstr " (SÃ¥ fort din arbetskatalog är ren, kör \"git rebase --continue\")" +msgstr " (SÃ¥ fort din arbetskatalog är ren, kör â€git rebase --continueâ€)" #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" -"Du hÃ¥ller pÃ¥ att redigera en incheckning medan du ombaserar grenen \"%s\" " -"ovanpÃ¥ \"%s\"." +"Du hÃ¥ller pÃ¥ att redigera en incheckning medan du ombaserar grenen â€%s†" +"ovanpÃ¥ â€%sâ€." msgid "You are currently editing a commit during a rebase." msgstr "Du hÃ¥ller pÃ¥ att redigera en incheckning under en ombasering." msgid " (use \"git commit --amend\" to amend the current commit)" msgstr "" -" (använd \"git commit --amend\" för att lägga till pÃ¥ aktuell incheckning)" +" (använd â€git commit --amend†för att lägga till pÃ¥ aktuell incheckning)" msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" -msgstr " (använd \"git rebase --continue\" när du är nöjd med dina ändringar)" +msgstr " (använd â€git rebase --continue†när du är nöjd med dina ändringar)" msgid "Cherry-pick currently in progress." msgstr "Cherry-pick pÃ¥gÃ¥r." #, c-format msgid "You are currently cherry-picking commit %s." -msgstr "Du hÃ¥ller pÃ¥ med en \"cherry-pick\" av incheckningen %s." +msgstr "Du hÃ¥ller pÃ¥ med en â€cherry-pick†av incheckningen %s." msgid " (fix conflicts and run \"git cherry-pick --continue\")" -msgstr " (rätta konflikter och kör sedan \"git cherry-pick --continue\")" +msgstr " (rätta konflikter och kör sedan â€git cherry-pick --continueâ€)" msgid " (run \"git cherry-pick --continue\" to continue)" -msgstr " (kör \"git cherry-pick --continue\" för att fortsätta)" +msgstr " (kör â€git cherry-pick --continue†för att fortsätta)" msgid " (all conflicts fixed: run \"git cherry-pick --continue\")" -msgstr " (alla konflikter rättade: kör \"git cherry-pick --continue\")" +msgstr " (alla konflikter rättade: kör â€git cherry-pick --continueâ€)" msgid " (use \"git cherry-pick --skip\" to skip this patch)" -msgstr " (använd \"git cherry-pick --skip\" för att hoppa över patchen)" +msgstr " (använd â€git cherry-pick --skip†för att hoppa över patchen)" msgid " (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)" msgstr "" -" (använd \"git cherry-pick --abort\" för att avbryta \"cherry-pick\"-" +" (använd â€git cherry-pick --abort†för att avbryta â€cherry-pickâ€-" "operationen)" msgid "Revert currently in progress." @@ -21842,30 +22029,30 @@ msgid "You are currently reverting commit %s." msgstr "Du hÃ¥ller pÃ¥ med att Ã¥ngra incheckningen %s." msgid " (fix conflicts and run \"git revert --continue\")" -msgstr " (rätta konflikter och kör sedan \"git revert --continue\")" +msgstr " (rätta konflikter och kör sedan â€git revert --continueâ€)" msgid " (run \"git revert --continue\" to continue)" -msgstr " (kör \"git revert --continue\" för att fortsätta)" +msgstr " (kör â€git revert --continue†för att fortsätta)" msgid " (all conflicts fixed: run \"git revert --continue\")" -msgstr " (alla konflikter rättade: kör \"git revert --continue\")" +msgstr " (alla konflikter rättade: kör â€git revert --continueâ€)" msgid " (use \"git revert --skip\" to skip this patch)" -msgstr " (använd \"git revert --skip\" för att hoppa över patchen)" +msgstr " (använd â€git revert --skip†för att hoppa över patchen)" msgid " (use \"git revert --abort\" to cancel the revert operation)" -msgstr " (använd \"git revert --abort\" för att avbryta Ã¥ngrandet)" +msgstr " (använd â€git revert --abort†för att avbryta Ã¥ngrandet)" #, c-format msgid "You are currently bisecting, started from branch '%s'." -msgstr "Du hÃ¥ller pÃ¥ med en \"bisect\", startad frÃ¥n grenen \"%s\"." +msgstr "Du hÃ¥ller pÃ¥ med en â€bisectâ€, startad frÃ¥n grenen â€%sâ€." msgid "You are currently bisecting." -msgstr "Du hÃ¥ller pÃ¥ med en \"bisect\"." +msgstr "Du hÃ¥ller pÃ¥ med en â€bisectâ€." msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr "" -" (använd \"git bisect reset\" för att komma tillbaka till ursprungsgrenen)" +" (använd â€git bisect reset†för att komma tillbaka till ursprungsgrenen)" msgid "You are in a sparse checkout." msgstr "Du är i en gles utcheckning." @@ -21917,7 +22104,7 @@ msgid "It took %.2f seconds to enumerate untracked files." msgstr "Det tog %.2f sekunder att räkna upp ospÃ¥rade filer." msgid "See 'git help status' for information on how to improve this." -msgstr "Se \"git help status\" för information om hur du kan förbättra detta." +msgstr "Se â€git help status†för information om hur du kan förbättra detta." # %s är nästa sträng eller tom. #, c-format @@ -21933,8 +22120,7 @@ msgstr "Inga ändringar" #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" -"inga ändringar att checka in (använd \"git add\" och/eller \"git commit -a" -"\")\n" +"inga ändringar att checka in (använd â€git add†och/eller â€git commit -aâ€)\n" #, c-format msgid "no changes added to commit\n" @@ -21945,8 +22131,7 @@ msgid "" "nothing added to commit but untracked files present (use \"git add\" to " "track)\n" msgstr "" -"inget köat för incheckning, men ospÃ¥rade filer finns (spÃ¥ra med \"git add" -"\")\n" +"inget köat för incheckning, men ospÃ¥rade filer finns (spÃ¥ra med â€git addâ€)\n" #, c-format msgid "nothing added to commit but untracked files present\n" @@ -21954,7 +22139,7 @@ msgstr "inget köat för incheckning, men ospÃ¥rade filer finns\n" #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" -msgstr "inget att checka in (skapa/kopiera filer och spÃ¥ra med \"git add\")\n" +msgstr "inget att checka in (skapa/kopiera filer och spÃ¥ra med â€git addâ€)\n" #, c-format msgid "nothing to commit\n" @@ -21995,6 +22180,10 @@ msgstr "dessutom innehÃ¥ller dit index ändringar som inte har checkats in." msgid "cannot %s: Your index contains uncommitted changes." msgstr "kan inte %s: Ditt index innehÃ¥ller ändringar som inte checkats in." +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "okänd stil â€%s†angavs för â€%sâ€" + msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" @@ -22068,7 +22257,7 @@ msgstr "lokal tidszonförskjutning större än eller lika med 24 timmar\n" #, perl-format msgid "fatal: command '%s' died with exit code %d" -msgstr "ödesdigert: kommandot \"%s\" dog med slutkoden %d" +msgstr "ödesdigert: kommandot â€%s†dog med slutkoden %d" msgid "the editor exited uncleanly, aborting everything" msgstr "textredigeringsprogrammet avslutades med fel, avbryter allting" @@ -22076,12 +22265,11 @@ msgstr "textredigeringsprogrammet avslutades med fel, avbryter allting" #, perl-format msgid "" "'%s' contains an intermediate version of the email you were composing.\n" -msgstr "" -"\"%s\" innehÃ¥ller en mellanliggande version av e-postbrevet du skrev.\n" +msgstr "â€%s†innehÃ¥ller en mellanliggande version av e-postbrevet du skrev.\n" #, perl-format msgid "'%s.final' contains the composed email.\n" -msgstr "\"%s.final\" innehÃ¥ller det skrivna brevet.\n" +msgstr "â€%s.final†innehÃ¥ller det skrivna brevet.\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases är inkompatibelt med andra flaggor\n" @@ -22091,9 +22279,9 @@ msgid "" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" "Set sendemail.forbidSendmailVariables to false to disable this check.\n" msgstr "" -"ödesdigert: hittade konfigurationsflaggor för \"sendmail\"\n" -"git-send-email konfigureras med \"sendemail.*\"-flaggor - lägg märke till \"e" -"\".\n" +"ödesdigert: hittade konfigurationsflaggor för â€sendmailâ€\n" +"git-send-email konfigureras med â€sendemail.*â€-flaggor - lägg märke till " +"â€eâ€.\n" "Sätt sendemail.forbidSendmailVariables till false för att inaktivera denna " "kontroll.\n" @@ -22104,16 +22292,16 @@ msgid "" "`batch-size` and `relogin` must be specified together (via command-line or " "configuration option)\n" msgstr "" -"\"batch-size\" och \"relogin\" mÃ¥ste anges tillsammans (via kommandorad " -"eller konfigurationsflagga)\n" +"â€batch-size†och â€relogin†mÃ¥ste anges tillsammans (via kommandorad eller " +"konfigurationsflagga)\n" #, perl-format msgid "Unknown --suppress-cc field: '%s'\n" -msgstr "Okänt fält i --suppress-cc: \"%s\"\n" +msgstr "Okänt fält i --suppress-cc: â€%sâ€\n" #, perl-format msgid "Unknown --confirm setting: '%s'\n" -msgstr "Okänd inställning i --confirm: \"%s\"\n" +msgstr "Okänd inställning i --confirm: â€%sâ€\n" #, perl-format msgid "warning: sendmail alias with quotes is not supported: %s\n" @@ -22121,11 +22309,11 @@ msgstr "varning: sendmail-alias med citationstecken stöds inte. %s\n" #, perl-format msgid "warning: `:include:` not supported: %s\n" -msgstr "varning: \":include:\" stöds inte: %s\n" +msgstr "varning: â€:include:†stöds inte: %s\n" #, perl-format msgid "warning: `/file` or `|pipe` redirection not supported: %s\n" -msgstr "varning: omdirigering til \"/fil\" eller \"|rör\" stöds inte: %s\n" +msgstr "varning: omdirigering til â€/fil†eller â€|rör†stöds inte: %s\n" #, perl-format msgid "warning: sendmail line is not recognized: %s\n" @@ -22139,10 +22327,10 @@ msgid "" " * Saying \"./%s\" if you mean a file; or\n" " * Giving --format-patch option if you mean a range.\n" msgstr "" -"Filen \"%s\" finns men kan ocksÃ¥ vara ett incheckningsintervall\n" +"Filen â€%s†finns men kan ocksÃ¥ vara ett incheckningsintervall\n" "att skapa patchar för. Gör otvetydigt genom att...\n" "\n" -" * Säga \"./%s\" om du menar en fil; eller\n" +" * Säga â€./%s†om du menar en fil; eller\n" " * Ange flaggan --format-patch om du menar ett intervall.\n" #, perl-format @@ -22173,20 +22361,20 @@ msgid "" "\n" "Clear the body content if you don't wish to send a summary.\n" msgstr "" -"Rader som börjar med \"GIT:\" kommer tas bort.\n" +"Rader som börjar med â€GIT:†kommer tas bort.\n" "Överväg att ta med en övergripande diffstatus eller\n" "innehÃ¥llsförteckning för patchen du skriver.\n" "\n" "Rensa brevkroppen om du inte vill sända nÃ¥gon sammanfattning.\n" #, perl-format -msgid "Failed to open %s: %s" -msgstr "Misslyckades öppna %s: %s" - -#, perl-format msgid "Failed to open %s.final: %s" msgstr "Misslyckades öppna %s.final: %s" +#, perl-format +msgid "Failed to open %s: %s" +msgstr "Misslyckades öppna %s: %s" + msgid "Summary email is empty, skipping it\n" msgstr "Sammanfattande brev tomt, hoppar över\n" @@ -22213,15 +22401,15 @@ msgid "" msgstr "" "Vägrar sända eftersom patchen\n" "\t%s\n" -"har mallärendet \"*** SUBJECT HERE ***\". Använd --force om du verkligen " -"vill sända.\n" +"har mallärendet â€*** SUBJECT HERE ***â€. Använd --force om du verkligen vill " +"sända.\n" msgid "To whom should the emails be sent (if anyone)?" msgstr "Till vem ska breven sändas (om nÃ¥gon)?" #, perl-format msgid "fatal: alias '%s' expands to itself\n" -msgstr "ödesdigert: aliaset \"%s\" expanderar till sig själv\n" +msgstr "ödesdigert: aliaset â€%s†expanderar till sig själv\n" msgid "Message-ID to be used as In-Reply-To for the first email (if any)? " msgstr "" @@ -22239,7 +22427,7 @@ msgstr "Vad vill du göra med adressen? (q=avsluta, d=kasta, e=redigera): " #, perl-format msgid "CA path \"%s\" does not exist" -msgstr "CA-sökvägen \"%s\" finns inte" +msgstr "CA-sökvägen â€%s†finns inte" msgid "" " The Cc list above has been expanded by additional\n" @@ -22259,9 +22447,9 @@ msgstr "" " Beteendet styrs av konfigurationsinställningen\n" " sendemail.confirm\n" "\n" -" För ytterligare information, kör \"git send-email --help\".\n" +" För ytterligare information, kör â€git send-email --helpâ€.\n" " För att behÃ¥lla nuvarande beteende, men dölja detta\n" -" meddelande, kör \"git config --global sendemail.confirm auto\".\n" +" meddelande, kör â€git config --global sendemail.confirm autoâ€.\n" "\n" #. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your @@ -22271,7 +22459,7 @@ msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): " msgstr "Sända brevet? (y=ja, n=nej, e=redigera, q=avsluta, a=alla): " msgid "Send this email reply required" -msgstr "Svar krävs pÃ¥ frÃ¥gan \"Sända brevet?\"" +msgstr "Svar krävs pÃ¥ frÃ¥gan â€Sända brevet?â€" msgid "The required SMTP server is not properly defined." msgstr "Nödvändig SMTP-server har inte angivits korrekt." @@ -22319,35 +22507,35 @@ msgstr "kan inte öppna filen %s" #, perl-format msgid "(mbox) Adding cc: %s from line '%s'\n" -msgstr "(mbox) Lägger till cc: %s frÃ¥n raden \"%s\"\n" +msgstr "(mbox) Lägger till cc: %s frÃ¥n raden â€%sâ€\n" #, perl-format msgid "(mbox) Adding to: %s from line '%s'\n" -msgstr "(mbox) Lägger till to: %s frÃ¥n raden \"%s\"\n" +msgstr "(mbox) Lägger till to: %s frÃ¥n raden â€%sâ€\n" #, perl-format msgid "(non-mbox) Adding cc: %s from line '%s'\n" -msgstr "(icke-mbox) Lägger till cc: %s frÃ¥n raden \"%s\"\n" +msgstr "(icke-mbox) Lägger till cc: %s frÃ¥n raden â€%sâ€\n" #, perl-format msgid "(body) Adding cc: %s from line '%s'\n" -msgstr "(kropp) Lägger till cc: %s frÃ¥n raden \"%s\"\n" +msgstr "(kropp) Lägger till cc: %s frÃ¥n raden â€%sâ€\n" #, perl-format msgid "(%s) Could not execute '%s'" -msgstr "(%s) Kunde inte köra \"%s\"" +msgstr "(%s) Kunde inte köra â€%sâ€" #, perl-format msgid "(%s) Malformed output from '%s'" -msgstr "(%s) Felformaterad utdata frÃ¥n \"%s\"" +msgstr "(%s) Felformaterad utdata frÃ¥n â€%sâ€" #, perl-format msgid "(%s) failed to close pipe to '%s'" -msgstr "(%s) misslyckades stänga röret till \"%s\"" +msgstr "(%s) misslyckades stänga röret till â€%sâ€" #, perl-format msgid "(%s) Adding %s: %s from: '%s'\n" -msgstr "(%s) Lägger till %s: %s frÃ¥n: \"%s\"\n" +msgstr "(%s) Lägger till %s: %s frÃ¥n: â€%sâ€\n" msgid "cannot send message as 7bit" msgstr "kan inte sända brev som sjubitars" @@ -22380,8 +22568,7 @@ msgstr "" #, perl-format msgid "Skipping %s with backup suffix '%s'.\n" msgstr "" -"Hoppar över %s med filnamnstillägget \"%s\" som används för " -"säkerhetskopior.\n" +"Hoppar över %s med filnamnstillägget â€%s†som används för säkerhetskopior.\n" #. TRANSLATORS: please keep "[y|N]" as is. #, perl-format @@ -1,8 +1,8 @@ # Turkish translations for Git # Git Türkçe çevirileri -# Copyright (C) 2020-2023 Emir SARI <emir_sari@icloud.com> +# Copyright (C) 2020-2024 Emir SARI <emir_sari@icloud.com> # This file is distributed under the same license as the Git package. -# Emir SARI <emir_sari@icloud.com>, 2020-2023 +# Emir SARI <emir_sari@icloud.com>, 2020-2024 # # ######################################################### # # Git Türkçe kavramlar dizini / Git Turkish Glossary # @@ -27,6 +27,7 @@ # detached HEAD | ayrık HEAD # # dirty | kirli # # evil merge | uÄŸursuz birleÅŸtirme # +# fanout | çıkış sayısı # # fast-forward | ileri sarım/sarmak # # fetch | getirme(k) # # fixup | düzeltmek # @@ -48,10 +49,10 @@ # pathspec | yol belirteci # # pattern | dizgi # # porcelain | okunabilir # -# prune | budamak # +# prune | buda(mak) # # pseudoref | yalancıktan baÅŸvuru # -# pull | çekme(k) # -# push | itme(k) # +# pull | çek(mek) # +# push | it(mek) # # rebase | yeniden temellendirme(k) # # record | kayıt yaz(mak) # # ref | baÅŸvuru # @@ -85,6 +86,7 @@ # trailer | artbilgi # # tree | aÄŸaç # # treeish | aÄŸacımsı # +# unborn | henüz doÄŸmamış (dal) # # unstage | hazırlıktan çıkar(mak) # # upstream | üstkaynak # # worktree/working tree | çalışma aÄŸacı # @@ -94,8 +96,8 @@ msgid "" msgstr "" "Project-Id-Version: Git Turkish Localization Project\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-16 14:34+0300\n" -"PO-Revision-Date: 2023-08-16 15:00+0300\n" +"POT-Creation-Date: 2024-02-16 22:04+0300\n" +"PO-Revision-Date: 2024-02-16 22:00+0300\n" "Last-Translator: Emir SARI <emir_sari@icloud.com>\n" "Language-Team: Turkish (https://github.com/bitigchi/git-po/)\n" "Language: tr\n" @@ -1500,6 +1502,10 @@ msgid "Unexpected option --output" msgstr "Beklenmedik seçenek --output" #, c-format +msgid "extra command line parameter '%s'" +msgstr "fazladan komut satırı parametresi '%s'" + +#, c-format msgid "Unknown archive format '%s'" msgstr "Bilinmeyen arÅŸiv biçimi '%s'" @@ -1545,6 +1551,14 @@ msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "hatalı --attr-source veya GIT_ATTR_SOURCE" #, c-format +msgid "unable to stat '%s'" +msgstr "'%s' dosyasının bilgileri alınamıyor" + +#, c-format +msgid "unable to read %s" +msgstr "%s okunamıyor" + +#, c-format msgid "Badly quoted content in file '%s': %s" msgstr "'%s' dosyasında hatalı tırnaÄŸa alınmış içerik: %s" @@ -1830,8 +1844,8 @@ msgid "submodule '%s': cannot create branch '%s'" msgstr "'%s' altmodülü: '%s' dalı oluÅŸturulamıyor" #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "'%s' çıkışı '%s' konumunda halihazırda yapılmış" +msgid "'%s' is already used by worktree at '%s'" +msgstr "'%s', '%s' konumunda halihazırda çalışma aÄŸacı tarafından kullanılıyor" msgid "git add [<options>] [--] <pathspec>..." msgstr "git add [<seçenekler>] [--] <yol-blrtç>..." @@ -1850,24 +1864,21 @@ msgstr "" "add.interactive.useBuiltin ayarı kaldırıldı!\n" "Ayrıntılar için onun 'git help config' içindeki girdisine bakın." -msgid "Could not read the index" -msgstr "İndeks okunamadı" - -msgid "Could not write patch" -msgstr "Yama yazılamadı" +msgid "could not read the index" +msgstr "indeks okunamadı" msgid "editing patch failed" msgstr "yamayı düzenleme baÅŸarısız" #, c-format -msgid "Could not stat '%s'" -msgstr "'%s' dosya bilgileri alınamadı" +msgid "could not stat '%s'" +msgstr "'%s' bilgileri alınamadı" -msgid "Empty patch. Aborted." -msgstr "BoÅŸ yama. İptal edildi." +msgid "empty patch. aborted" +msgstr "boÅŸ yama. iptal edildi." #, c-format -msgid "Could not apply '%s'" +msgid "could not apply '%s'" msgstr "'%s' uygulanamadı" msgid "The following paths are ignored by one of your .gitignore files:\n" @@ -1998,6 +2009,9 @@ msgstr "" msgid "index file corrupt" msgstr "indeks dosyası hasarlı" +msgid "unable to write new index file" +msgstr "yeni indeks dosyası yazılamıyor" + #, c-format msgid "bad action '%s' for '%s'" msgstr "hatalı eylem '%s', '%s' için" @@ -2206,9 +2220,6 @@ msgstr "" "Bir dosyanın \"onlar sildi\" olduÄŸunu kabul etmek için dosya ile 'git rm' " "yapabilirsiniz." -msgid "unable to write new index file" -msgstr "yeni indeks dosyası yazılamıyor" - #, c-format msgid "Could not parse object '%s'." msgstr "'%s' nesnesi ayrıştırılamadı." @@ -2227,10 +2238,6 @@ msgstr "" msgid "failed to read '%s'" msgstr "'%s' okunamadı" -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "'%s=%s' ve '%s=%s' seçenekleri birlikte kullanılamaz" - msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<seçenekler>] [(<mbox> | <posta-dizin>)...]" @@ -2382,11 +2389,11 @@ msgid "git archive: expected a flush" msgstr "git archive: FloÅŸ bekleniyordu" msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=<terim> --term-{old,good}=<terim>] [--" -"no-checkout] [--first-parent] [<kötü> [<iyi>...]] [--] [<yol-blrtç>...]" +"git bisect start [--term-(new|bad)=<uçbirim> --term-(old|good)=<uçbirim>] " +"[--no-checkout] [--first-parent] [<kötü> [<iyi>...]] [--] [<yol-blrtç>...]" msgid "git bisect (good|bad) [<rev>...]" msgstr "git bisect (good|bad) [<rev>...]" @@ -2400,8 +2407,8 @@ msgstr "git bisect reset [<iÅŸleme>]" msgid "git bisect replay <logfile>" msgstr "git bisect replay <günlük-dosyası>" -msgid "git bisect run <cmd>..." -msgstr "git bisect run <komut>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <komut> [<argüman>...]" #, c-format msgid "cannot open file '%s' in mode '%s'" @@ -2812,7 +2819,7 @@ msgstr "git branch [<seçenekler>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" "'%s' dalı siliniyor: Bu dal '%s'\n" " dalına birleÅŸtirilmiÅŸ; ancak HEAD'e henüz birleÅŸtirilmemiÅŸ." @@ -2820,36 +2827,37 @@ msgstr "" #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" "'%s' dalı silinmiyor: Bu dal HEAD'e birleÅŸtirilmiÅŸ olmasına raÄŸmen\n" " '%s' dalına birleÅŸtirilmemiÅŸ." #, c-format -msgid "Couldn't look up commit object for '%s'" +msgid "couldn't look up commit object for '%s'" msgstr "'%s' için iÅŸleme nesnesi aranamadı" #, 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 "" -"'%s' dalı tümüyle birleÅŸtirilmemiÅŸ.\n" -"EÄŸer silmek istediÄŸinizden eminseniz 'git branch -D %s' çalıştırın." +msgid "the branch '%s' is not fully merged" +msgstr "'%s' dalı tümüyle birleÅŸtirilmedi" -msgid "Update of config-file failed" -msgstr "config-file güncellemesi baÅŸarısız" +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" +msgstr "Onu silmek istediÄŸinizden eminseniz 'git branch -D %s' çalıştırın." + +msgid "update of config-file failed" +msgstr "config-file güncellenemedi" msgid "cannot use -a with -d" msgstr "-a, -d ile kullanılamıyor" #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "'%s' dalı silinemiyor, ÅŸurada çıkış yapılmış: '%s'" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "" +"'%s' konumundaki çalışma aÄŸacı tarafından kullanılan '%s' dalı silinemiyor" #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "Uzak izleme dalı '%s' bulunamadı." +msgid "remote-tracking branch '%s' not found" +msgstr "uzak izleme dalı '%s' bulunamadı" #, c-format msgid "" @@ -2860,8 +2868,8 @@ msgstr "" "--remote yazmayı mı unuttunuz?" #, c-format -msgid "branch '%s' not found." -msgstr "'%s' dalı bulunamadı." +msgid "branch '%s' not found" +msgstr "'%s' dalı bulunamadı" #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" @@ -2882,11 +2890,11 @@ msgid "HEAD (%s) points outside of refs/heads/" msgstr "HEAD (%s), refs/heads/ dışına iÅŸaret ediyor" #, c-format -msgid "Branch %s is being rebased at %s" +msgid "branch %s is being rebased at %s" msgstr "%s dalı %s konumunda yeniden temellendiriliyor" #, c-format -msgid "Branch %s is being bisected at %s" +msgid "branch %s is being bisected at %s" msgstr "%s dalı %s konumunda ikili aranıyor" #, c-format @@ -2894,40 +2902,40 @@ msgid "HEAD of working tree %s is not updated" msgstr "%s çalışma aÄŸacının HEAD'i güncellenmemiÅŸ" #, c-format -msgid "Invalid branch name: '%s'" -msgstr "Geçersiz dal adı: '%s'" +msgid "invalid branch name: '%s'" +msgstr "geçersiz dal adı: '%s'" #, c-format -msgid "No commit on branch '%s' yet." -msgstr "'%s' dalında henüz bir iÅŸleme yok." +msgid "no commit on branch '%s' yet" +msgstr "'%s' dalında henüz bir iÅŸleme yok" #, c-format -msgid "No branch named '%s'." -msgstr "'%s' adında bir dal yok." +msgid "no branch named '%s'" +msgstr "'%s' adında bir dal yok" -msgid "Branch rename failed" -msgstr "Dal yeniden adlandırması baÅŸarısız" +msgid "branch rename failed" +msgstr "dal yeniden adlandırılamadı" -msgid "Branch copy failed" -msgstr "Dal kopyalaması baÅŸarısız" +msgid "branch copy failed" +msgstr "dal kopyalanamadı" #, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "Yanlış adlandırılan '%s' dalının bir kopyası oluÅŸturuldu" +msgid "created a copy of a misnamed branch '%s'" +msgstr "yanlış adlandırılan '%s' dalının bir kopyası oluÅŸturuldu" #, c-format -msgid "Renamed a misnamed branch '%s' away" -msgstr "Yanlış adlandırılan '%s' dalı yeniden adlandırıldı" +msgid "renamed a misnamed branch '%s' away" +msgstr "yanlış adlandırılan '%s' dalı yeniden adlandırıldı" #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "Dal %s olarak yeniden adlandırıldı; ancak HEAD güncellenmedi!" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "dal %s olarak yeniden adlandırıldı; ancak HEAD güncellenmedi!" -msgid "Branch is renamed, but update of config-file failed" -msgstr "Dal yeniden adlandırıldı; ancak config-file güncellemesi baÅŸarısız" +msgid "branch is renamed, but update of config-file failed" +msgstr "dal yeniden adlandırıldı; ancak config-file güncellenemedi" -msgid "Branch is copied, but update of config-file failed" -msgstr "Dal kopyalandı; ancak config-file güncellemesi baÅŸarısız" +msgid "branch is copied, but update of config-file failed" +msgstr "dal kopyalandı; ancak config-file güncellenemedi" #, c-format msgid "" @@ -3041,8 +3049,8 @@ msgstr "altmodüller içinden özyinele" msgid "format to use for the output" msgstr "çıktı için kullanılacak biçim" -msgid "Failed to resolve HEAD as a valid ref." -msgstr "HEAD geçerli bir baÅŸvuru olarak çözülemedi." +msgid "failed to resolve HEAD as a valid ref" +msgstr "HEAD geçerli bir baÅŸvuru olarak çözülemedi" msgid "HEAD not found below refs/heads!" msgstr "HEAD, refs/heads altında bulunamadı!" @@ -3060,17 +3068,17 @@ msgstr "--recurse-submodules, yalnızca dal oluÅŸturmada kullanılabilir" msgid "branch name required" msgstr "dal adı gerekli" -msgid "Cannot give description to detached HEAD" -msgstr "Ayrılmış HEAD'e açıklama verilemiyor" +msgid "cannot give description to detached HEAD" +msgstr "ayrık HEAD'e açıklama verilemiyor" msgid "cannot edit description of more than one branch" msgstr "birden çok dalın açıklaması düzenlenemiyor" -msgid "cannot copy the current branch while not on any." -msgstr "Bir dalın üzerinde deÄŸilken geçerli dal kopyalanamaz." +msgid "cannot copy the current branch while not on any" +msgstr "bir dalın üzerinde deÄŸilken geçerli dal kopyalanamaz" -msgid "cannot rename the current branch while not on any." -msgstr "Bir dalın üzerinde deÄŸilken geçerli dal yeniden adlandırılamaz." +msgid "cannot rename the current branch while not on any" +msgstr "bir dalın üzerinde deÄŸilken geçerli dal yeniden adlandırılamaz" msgid "too many branches for a copy operation" msgstr "bir kopyalama iÅŸlemi için pek fazla dal" @@ -3083,10 +3091,10 @@ msgstr "yeni üstkaynak ayarlamak için pek fazla argüman" #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." +"could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" "HEAD'in üst kaynağı %s olarak ayarlanamadı; çünkü herhangi bir dala iÅŸaret " -"etmiyor." +"etmiyor" #, c-format msgid "no such branch '%s'" @@ -3099,16 +3107,16 @@ msgstr "'%s' diye bir dal yok" msgid "too many arguments to unset upstream" msgstr "üst kaynağı kaldırmak için pek fazla argüman" -msgid "could not unset upstream of HEAD when it does not point to any branch." +msgid "could not unset upstream of HEAD when it does not point to any branch" msgstr "" -"HEAD'in üst kaynağı kaldırılamadı; çünkü herhangi bir dala iÅŸaret etmiyor." +"HEAD'in üst kaynağı kaldırılamadı; çünkü herhangi bir dala iÅŸaret etmiyor" #, c-format -msgid "Branch '%s' has no upstream information" +msgid "branch '%s' has no upstream information" msgstr "'%s' dalının üstkaynak bilgisi yok" msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"the -a, and -r, options to 'git branch' do not take a branch name.\n" "Did you mean to use: -a|-r --list <pattern>?" msgstr "" "'git branch'in -a ve -r seçenekleri bir dal adı almaz.\n" @@ -3116,10 +3124,10 @@ msgstr "" msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." +"'--set-upstream-to' instead" msgstr "" "--set-upstream seçeneÄŸi artık desteklenmiyor. Lütfen --track veya --set-" -"upstream-to kullanın." +"upstream-to kullanın" msgid "git version:\n" msgstr "git sürümü:\n" @@ -3192,6 +3200,10 @@ msgid "specify a strftime format suffix for the filename(s)" msgstr "dosya adları için bir strftime biçim soneki belirtin" #, c-format +msgid "unknown argument `%s'" +msgstr "bilinmeyen argüman '%s'" + +#, c-format msgid "could not create leading directories for '%s'" msgstr "'%s' için öncü dizinler oluÅŸturulamadı" @@ -3298,6 +3310,13 @@ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" msgstr "git cat-file (-t | -s) [--allow-unknown-type] <nesne>" msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<baÅŸvuru>:<yol|aÄŸacımsı> | --path=<yol|aÄŸacımsı> <revizyon>]" + +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -3308,13 +3327,6 @@ msgstr "" " [--buffer] [--follow-symlinks] [--unordered]\n" " [--textconv | --filters] [-Z]" -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<baÅŸvuru>:<yol|aÄŸacımsı> | --path=<yol|aÄŸacımsı> <revizyon>]" - msgid "Check object existence or emit object contents" msgstr "Nesne varlığını denetle veya nesne içeriÄŸini yay" @@ -3611,6 +3623,10 @@ msgid "'%s' or '%s' cannot be used with %s" msgstr "'%s' veya '%s', %s ile birlikte kullanılamaz" #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "'%s', '%s' veya '%s' bir aÄŸaçtan çıkış yaparken kullanılamaz" + +#, c-format msgid "path '%s' is unmerged" msgstr "'%s' yolu birleÅŸtirilmemiÅŸ" @@ -3861,8 +3877,8 @@ msgstr "zorla çıkış yap (yerel deÄŸiÅŸiklikleri çöpe at)" msgid "new-branch" msgstr "yeni dal" -msgid "new unparented branch" -msgstr "yeni üst ögesi olmayan dal" +msgid "new unborn branch" +msgstr "yeni henüz doÄŸmamış dal" msgid "update ignored files (default)" msgstr "yok sayılan dosyaları güncelle (öntanımlı)" @@ -4113,9 +4129,6 @@ msgstr "" "clean.requireForce öntanımlı olarak 'true' ve ne -i ne -n ne de -f verilmiÅŸ; " "temizleme reddediliyor" -msgid "-x and -X cannot be used together" -msgstr "-x ve -X birlikte kullanılamaz" - msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<seçenekler>] [--] <depo> [<dizin>]" @@ -4203,6 +4216,9 @@ msgstr "git dizini" msgid "separate git dir from working tree" msgstr "git dizinini çalışma aÄŸacından ayır" +msgid "specify the reference format to use" +msgstr "kullanılacak baÅŸvuru biçimini belirt" + msgid "key=value" msgstr "anahtar=deÄŸer" @@ -4320,11 +4336,9 @@ msgstr "Çok fazla argüman." msgid "You must specify a repository to clone." msgstr "Klonlamak için bir depo belirtmelisiniz." -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "" -"--bundle-uri; --depth, --shallow-since ve --shallow-exclude ile uyumsuz" +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "bilinmeyen baÅŸvuru depolama biçimi '%s'" #, c-format msgid "repository '%s' does not exist" @@ -4452,11 +4466,11 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <dizin>] [--append]\n" -" [--split[=<<strateji>]] [--reachable | --stdin-packs " -"| --stdin-commits]\n" +" [--split[=<strateji>]] [--reachable | --stdin-packs | " +"--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" " <bölme-seçenekleri>" @@ -4475,6 +4489,10 @@ msgid "Could not open commit-graph '%s'" msgstr "commit-graph '%s' açılamadı" #, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "commit-graph zinciri '%s' açılamadı" + +#, c-format msgid "unrecognized --split argument, %s" msgstr "tanımlanamayan --split argümanı, %s" @@ -4675,9 +4693,6 @@ msgstr "geçici indeks güncellenemiyor" msgid "Failed to update main cache tree" msgstr "Ana önbellek aÄŸacı güncellenemedi" -msgid "unable to write new_index file" -msgstr "new_index dosyası yazılamıyor" - msgid "cannot do a partial commit during a merge." msgstr "Bir birleÅŸtirme sırasında kısmi iÅŸleme yapılamaz." @@ -5083,10 +5098,10 @@ msgstr "İşleme iletisi gövdesinin boÅŸ bırakılmasından ötürü iptal edil msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" -"Depo güncellendi; ancak new_index dosyası yazılamıyor.\n" +"Depo güncellendi; ancak yeni indeks dosyası yazılamıyor.\n" "Diskin dolu olup olmadığını ve kotanızı aşıp aÅŸmadığınızı denetleyin,\n" "sonra kurtarmak için \"git restore --staged :/\" kullanın." @@ -6531,6 +6546,9 @@ msgstr "baÅŸvurulmayan nesneleri buda" msgid "pack unreferenced objects separately" msgstr "baÅŸvurulmamış nesneleri ayrı olarak paketle" +msgid "with --cruft, limit the size of new cruft packs" +msgstr "--cruft ile yeni süprüntü paketlerinin boyutunu sınırla" + msgid "be more thorough (increased runtime)" msgstr "biraz daha titiz ol (artırılmış iÅŸleyiÅŸ süresi)" @@ -6701,12 +6719,6 @@ msgstr "'crontab' çalıştırılamadı; sisteminiz 'cron' desteklemiyor olabili msgid "'crontab' died" msgstr "'crontab' beklenmedik bir biçimde sonlandı" -msgid "failed to start systemctl" -msgstr "systemctl baÅŸlatılamadı" - -msgid "failed to run systemctl" -msgstr "systemctl çalıştırılamadı" - #, c-format msgid "failed to delete '%s'" msgstr "'%s' silinemedi" @@ -6715,6 +6727,12 @@ msgstr "'%s' silinemedi" msgid "failed to flush '%s'" msgstr "'%s' floÅŸ yapılamadı" +msgid "failed to start systemctl" +msgstr "systemctl baÅŸlatılamadı" + +msgid "failed to run systemctl" +msgstr "systemctl çalıştırılamadı" + #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "tanımlanamayan --scheduler argümanı, '%s'" @@ -6738,6 +6756,9 @@ msgstr "görev planlayıcı" msgid "scheduler to trigger git maintenance run" msgstr "git bakımını tetikleyecek görev planlayıcı" +msgid "failed to set up maintenance schedule" +msgstr "bakım programı ayarlanamadı" + msgid "failed to add repo to global config" msgstr "depo, global yapılandırmaya eklenemedi" @@ -6769,6 +6790,10 @@ msgid "unable to read tree (%s)" msgstr "aÄŸaç okunamıyor (%s)" #, c-format +msgid "unable to read tree %s" +msgstr "%s aÄŸacı okunamıyor" + +#, c-format msgid "unable to grep from object of type %s" msgstr "%s türündeki bir nesneden grep yapılamıyor" @@ -6812,8 +6837,8 @@ msgstr "ikili dosyaları textconv süzgeçleri ile iÅŸle" msgid "search in subdirectories (default)" msgstr "altdizinlerde ara (öntanımlı)" -msgid "descend at most <depth> levels" -msgstr "en çok <derinlik> düzey in" +msgid "descend at most <n> levels" +msgstr "en çok <n> düzey aÅŸağı in" msgid "use extended POSIX regular expressions" msgstr "geniÅŸletilmiÅŸ POSIX düzenli ifadelerini kullan" @@ -7181,10 +7206,6 @@ msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "%s İLE SHA1 ÇARPIÅžMASI BULUNDU!" #, c-format -msgid "unable to read %s" -msgstr "%s okunamıyor" - -#, c-format msgid "cannot read existing object info %s" msgstr "var olan nesne bilgisi %s okunamıyor" @@ -7324,13 +7345,15 @@ msgstr "paket nesnelerinde fsck hatası" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" "git init [-q | --quiet] [--bare] [--template=<ÅŸablon-dizini>]\n" " [--separate-git-dir <git-dizini>] [--object-format=<biçim>]\n" +" [--ref-format=<biçim>]\n" " [-b <dal-adı> | --initial-branch=<dal-adı>]\n" -" [--shared[=<izinler>]] [<dizin>]" +" [--shared[=<izin>]] [<dizin>]" msgid "permissions" msgstr "izinler" @@ -7372,11 +7395,12 @@ msgstr "--separate-git-dir, çıplak depo ile uyumsuz" msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <jeton>[(=|:)<deÄŸer>])...]\n" +" [(--trailer (<anahtar>|<anArması>)" +"[(=|:)<deÄŸer>])...]\n" " [--parse] [<dosya>...]" msgid "edit files in place" @@ -7385,6 +7409,9 @@ msgstr "dosyaları yerinde düzenle" msgid "trim empty trailers" msgstr "boÅŸ artbilgileri kırp" +msgid "placement" +msgstr "yerleÅŸtirme" + msgid "where to place the new trailer" msgstr "yeni artbilgiler nereye yerleÅŸtirilecek" @@ -7397,17 +7424,17 @@ msgstr "artbilgi eksikse yapılacak eylem" msgid "output only the trailers" msgstr "yalnızca artbilgileri çıktı ver" -msgid "do not apply config rules" -msgstr "yapılandırma kurallarını uygulama" +msgid "do not apply trailer.* configuration variables" +msgstr "trailer.* yapılandırma deÄŸiÅŸkenlerini uygulama" -msgid "join whitespace-continued values" -msgstr "boÅŸluk ile sürdürülen deÄŸerleri uç uca ekle" +msgid "reformat multiline trailer values as single-line values" +msgstr "çok satırlı artbilgileri tek satırlı deÄŸerler olarak biçimlendir" -msgid "set parsing options" -msgstr "ayrıştırma seçeneklerini ayarla" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "--only-trailers --only-input --unfold için arma" -msgid "do not treat --- specially" -msgstr "ayırma çizgilerine (---) özel davranma" +msgid "do not treat \"---\" as the end of input" +msgstr "\"---\" dizgisine satır sonu olarak davranma" msgid "trailer(s) to add" msgstr "eklenecek artbilgi(ler)" @@ -7496,6 +7523,10 @@ msgstr "bir tam erim gerekiyor" msgid "not a range" msgstr "bir erim deÄŸil" +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "'%s' dal açıklama dosyası okunamıyor" + msgid "cover letter needs email format" msgstr "ön yazı için e-posta biçimi gerekli" @@ -7594,6 +7625,9 @@ msgstr "açıklama kipinden kapak sayfası kipi" msgid "generate parts of a cover letter based on a branch's description" msgstr "ön yazının bazı kısımlarını dalın açıklamasından oluÅŸtur" +msgid "use branch description from file" +msgstr "dal açıklamasını dosyadan oku" + msgid "use [<prefix>] instead of [PATCH]" msgstr "[PATCH] yerine [<önek>] kullan" @@ -8019,9 +8053,19 @@ msgstr "" "git merge-file [<seçenekler>] [-L <ad1> [-L <orij> [-L <ad2>]]] <dosya1> " "<orij-dosya> <dosya2>" +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"diff-algorithm seçeneÄŸi ÅŸunları kabul eder: \"myers\", \"minimal\", " +"\"patience\" ve \"histogram\"" + msgid "send results to standard output" msgstr "sonuçları standart çıktıya gönder" +msgid "use object IDs instead of filenames" +msgstr "dosya adları yerine nesne kimlikleri kullan" + msgid "use a diff3 based merge" msgstr "diff3 tabanlı birleÅŸtirme kullan" @@ -8037,6 +8081,12 @@ msgstr "çakışmalarda onların sürümünü kullan" msgid "for conflicts, use a union version" msgstr "çakışmalarda birlik olmuÅŸ bir sürüm kullan" +msgid "<algorithm>" +msgstr "<algoritma>" + +msgid "choose a diff algorithm" +msgstr "bir diff algoritması seç" + msgid "for conflicts, use this marker size" msgstr "çakışmalarda bu imleyici boyutunu kullan" @@ -8047,6 +8097,13 @@ msgid "set labels for file1/orig-file/file2" msgstr "file1/orig-file/file2 için etiketler yapıştır" #, c-format +msgid "object '%s' does not exist" +msgstr "'%s' diye bir nesne yok" + +msgid "Could not write object file" +msgstr "nesne dosyası yazılamadı" + +#, c-format msgid "unknown option %s" msgstr "bilinmeyen seçenek %s" @@ -8107,11 +8164,18 @@ msgstr "girdi satırı başına bir adet çoklu birleÅŸtirmeler gerçekleÅŸtir" msgid "specify a merge-base for the merge" msgstr "birleÅŸtirme için bir birleÅŸtirme temeli belirtilmeli" +msgid "option=value" +msgstr "seçenek=deÄŸer" + +msgid "option for selected merge strategy" +msgstr "seçili birleÅŸtirme stratejisi için seçenekler" + msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge, tüm diÄŸer seçeneklerle uyumsuz" -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base, --stdin ile uyumsuz" +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "bilinmeyen strateji seçeneÄŸi: -X%s" #, c-format msgid "malformed input line: '%s'." @@ -8180,12 +8244,6 @@ msgstr "strateji" msgid "merge strategy to use" msgstr "kullanılacak birleÅŸtirme stratejisi" -msgid "option=value" -msgstr "seçenek=deÄŸer" - -msgid "option for selected merge strategy" -msgstr "seçili birleÅŸtirme stratejisi için seçenekler" - msgid "merge commit message (for a non-fast-forward merge)" msgstr "" "birleÅŸtirme iÅŸlemesi iletisi (ileri sarım olmayan bir birleÅŸtirme için)" @@ -8247,10 +8305,6 @@ msgid "Not handling anything other than two heads merge." msgstr "İki uç iÅŸlemenin birleÅŸtirilmesi dışında bir ÅŸey yapılmıyor." #, c-format -msgid "unknown strategy option: -X%s" -msgstr "bilinmeyen strateji seçeneÄŸi: -X%s" - -#, c-format msgid "unable to write %s" msgstr "%s yazılamıyor" @@ -8540,8 +8594,8 @@ msgstr "hedef konum var" msgid "can not move directory into itself" msgstr "dizin kendi içine taşınamıyor" -msgid "cannot move directory over file" -msgstr "dizin dosya üzerinden taşınamıyor" +msgid "destination already exists" +msgstr "hedef halihazırda var" msgid "source directory is empty" msgstr "kaynak dizin boÅŸ" @@ -9048,6 +9102,10 @@ msgid "inconsistency with delta count" msgstr "delta sayımında tutarsızlık" #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "geçersiz pack.allowPackReuse deÄŸeri: '%s'" + +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -9284,9 +9342,6 @@ msgstr "olabilecek en küçük paket boyutu limiti 1 MiB'dır" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin bir indekslenebilir paket yapımında kullanılamaz" -msgid "cannot use --filter without --stdout" -msgstr "--filter, --stdout olmadan kullanılamaz" - msgid "cannot use --filter with --stdin-packs" msgstr "--filter, --stdin-packs ile birlikte kullanılamıyor" @@ -9299,19 +9354,16 @@ msgstr "iç revizyon listeleri, --cruft ile birlikte kullanılamıyor" msgid "cannot use --stdin-packs with --cruft" msgstr "--stdin-packs, --cruft ile birlikte kullanılamıyor" -msgid "cannot use --max-pack-size with --cruft" -msgstr "--max-pack-size, --cruft ile birlikte kullanılamıyor" - msgid "Enumerating objects" msgstr "Nesneler ortaya dökülüyor" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "Toplam %<PRIu32> (delta %<PRIu32>), yeniden kullanılan %<PRIu32> (delta " -"%<PRIu32>), yeniden kullanılan paket %<PRIu32>" +"%<PRIu32>), yeniden kullanılan paket %<PRIu32> (%<PRIuMAX> konumundan)" msgid "" "'git pack-redundant' is nominated for removal.\n" @@ -10274,16 +10326,6 @@ msgstr "" msgid "switch `C' expects a numerical value" msgstr "'C' anahtarı sayısal bir deÄŸer bekliyor" -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy, --merge veya --interactive gerektiriyor" - -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "" -"seçenekleri uygula, rebase.autoSquash ile uyumlu deÄŸil. --no-autosquash " -"eklemeyi düşünün" - msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -10696,10 +10738,10 @@ msgid_plural "" "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n" "to delete them, use:" msgstr[0] "" -"Not: refs/remotes hiyerarÅŸisi dışındaki bir dal kaldırılmadı;\n" +"Not: refs/remotes/ hiyerarÅŸisi dışındaki bir dal kaldırılmadı;\n" "onu silmek için ÅŸunu kullanın:" msgstr[1] "" -"Not: refs/remotes hiyerarÅŸisi dışındaki bazı dallar kaldırılmadı;\n" +"Not: refs/remotes/ hiyerarÅŸisi dışındaki bazı dallar kaldırılmadı;\n" "onları silmek için ÅŸunu kullanın:" #, c-format @@ -10985,6 +11027,10 @@ msgstr "baÅŸvurular anlık görüntü geçici dosyası kapatılamadı" msgid "could not remove stale bitmap: %s" msgstr "eskimiÅŸ biteÅŸlem kaldırılamadı: %s" +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "paket öneki %s, nesne dizini %s ile baÅŸlamıyor" + msgid "pack everything in a single pack" msgstr "her ÅŸeyi tek bir pakete sığdır" @@ -10998,7 +11044,7 @@ msgid "approxidate" msgstr "yaklaşık tarih" msgid "with --cruft, expire objects older than this" -msgstr "--cruft ile, bundan daha eski nesneleri yürürlükten kaldır" +msgstr "--cruft ile bundan daha eski nesneleri yürürlükten kaldır" msgid "remove redundant packs, and run git-prune-packed" msgstr "gereksiz paketleri kaldır ve 'git-prune-packed' çalıştır" @@ -11060,17 +11106,20 @@ msgstr "ortaya çıkan paketlerin bir çoklu paket indeksini yaz" msgid "pack prefix to store a pack containing pruned objects" msgstr "budanan nesneler içeren paketi depolamak için paket öneki" +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "süzülen nesneler içeren paketi depolamak için paket öneki" + msgid "cannot delete packs in a precious-objects repo" msgstr "bir precious-objects deposundaki paketler silinemiyor" +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "'%s' seçeneÄŸi, yalnızca '%s' ile birlikte kullanılabilir" + msgid "Nothing new to pack." msgstr "Paketlenecek yeni bir ÅŸey yok." #, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "paket öneki %s, nesne dizini %s ile baÅŸlamıyor" - -#, c-format msgid "renaming pack to '%s' failed" msgstr "paketi '%s' olarak yeniden adlandırma baÅŸarısız" @@ -11270,6 +11319,76 @@ msgstr "--convert-graft-file argüman almaz" msgid "only one pattern can be given with -l" msgstr "-l ile yalnızca bir dizgi verilebilir" +msgid "need some commits to replay" +msgstr "yeniden oynatmak için birkaç iÅŸleme gerekli" + +msgid "--onto and --advance are incompatible" +msgstr "--onto ve --advance birbiriyle uyumsuz" + +msgid "all positive revisions given must be references" +msgstr "verilen tüm pozitif revizyonlar, baÅŸvuru olmalı" + +msgid "argument to --advance must be a reference" +msgstr "--advance'a olan argüman bir baÅŸvuru olmalı" + +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "" +"birden çok kaynaklı hedef ilerletilemiyor; çünkü sıralama hatalı tanımlanmış " +"olurdu" + +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "" +"bunun --advance veya --onto iÅŸlemi olup olmadığı örtük olarak algılanamıyor" + +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "" +"birden çok kaynak dallı hedef ilerletilemiyor; çünkü sıralama hatalı " +"tanımlanmış olurdu" + +msgid "cannot implicitly determine correct base for --onto" +msgstr "--onto için olan doÄŸru temel örtük olarak algılanamıyor" + +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(DENEYSEL!) git replay ([--contained] --onto <yeni-temel> | --advance <dal>) " +"<revizyon-erimi>..." + +msgid "make replay advance given branch" +msgstr "verilen dalı önceden yeniden oynat" + +msgid "replay onto given commit" +msgstr "verilen iÅŸlemeye yeniden oynat" + +msgid "advance all branches contained in revision-range" +msgstr "revizyon eriminde içerilen tüm dalları ilerlet" + +msgid "option --onto or --advance is mandatory" +msgstr "--onto veya --advance seçeneÄŸinin kullanımı zorunlu" + +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "" +"'struct rev_info' içindeki '%s' biti zorlanacağından kimi revizyon yürütme " +"seçenekleri geçersiz kılınacak" + +msgid "error preparing revisions" +msgstr "revizyonlar hazırlanırken hata" + +msgid "replaying down to root commit is not supported yet!" +msgstr "kök iÅŸlemeye kadar yeniden oynatma henüz desteklenmiyor!" + +msgid "replaying merge commits is not supported yet!" +msgstr "birleÅŸtirme iÅŸlemelerini yeniden oynatma henüz desteklenmiyor!" + msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" msgstr "" @@ -11478,18 +11597,12 @@ msgstr "--prefix bir argüman gerektiriyor" msgid "unknown mode for --abbrev-ref: %s" msgstr "--abbrev-ref için bilinmeyen kip: %s" -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden, --branches ile birlikte kullanılamıyor" - -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden, --tags ile birlikte kullanılamıyor" - -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden, --remotes ile birlikte kullanılamıyor" - msgid "this operation must be run in a work tree" msgstr "bu iÅŸlem bir çalışma aÄŸacı içinde çalıştırılmalı" +msgid "Could not read the index" +msgstr "İndeks okunamadı" + #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "--show-object-format için bilinmeyen kip: %s" @@ -11833,23 +11946,44 @@ msgid "Unknown hash algorithm" msgstr "bilinmeyen saÄŸlama algoritması '%s'" msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<dizgi>...]" +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<baÅŸvuru>...]" + msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<dizgi>]" +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <baÅŸvuru>" + +msgid "reference does not exist" +msgstr "baÅŸvuru yok" + +msgid "failed to look up reference" +msgstr "baÅŸvuru bakılamadı" + msgid "only show tags (can be combined with heads)" msgstr "yalnızca etiketleri göster (dal uçlarıyla birlikte kullanılabilir)" msgid "only show heads (can be combined with tags)" msgstr "yalnızca dal uçlarını göster (etiketlerle birlikte kullanılabilir)" +msgid "check for reference existence without resolving" +msgstr "çözmeden baÅŸvuru varlığını denetle" + msgid "stricter reference checking, requires exact ref path" msgstr "daha sıkı baÅŸvuru denetlemesi; kesin baÅŸvuru yolu gerektirir" @@ -12661,6 +12795,9 @@ msgstr "" "shallow] [--reference <depo>] [--recursive] [--[no-]single-branch] [--] " "[<yol>...]" +msgid "Failed to resolve HEAD as a valid ref." +msgstr "HEAD geçerli bir baÅŸvuru olarak çözülemedi." + msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<seçenekler>] [<yol>...]" @@ -13119,6 +13256,9 @@ msgstr "(okunabilir veri için) kaydedilmiÅŸ çözülmeyen çakışmaları unut" msgid "write index in this format" msgstr "indeksi bu biçimle yaz" +msgid "report on-disk index format version" +msgstr "diskteki indeks biçimi sürümünü raporla" + msgid "enable or disable split index" msgstr "bölünmüş indeksi etkinleÅŸtir veya devre dışı bırak" @@ -13143,6 +13283,14 @@ msgstr "dosyaları dosya sistemi monitöründe geçerli olarak imle" msgid "clear fsmonitor valid bit" msgstr "dosya sistemi monitöründe geçerli kısmını temizle" +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "index-version: %d idi, %d olarak ayarlandı" + msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -13297,29 +13445,29 @@ msgstr "Olası kaynak dal yok, '--orphan' anlamı çıkarılıyor" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan -b %s %s\n" msgstr "" -"Bu depo için yeni bir yetim dal içeren (iÅŸlemesiz dal) bir\n" -"çalışma aÄŸacı oluÅŸturmak istediyseniz bunu --orphan bayrağı\n" -"ile yapabilirsiniz:\n" +"Bu depo için henüz doÄŸmamış bir dal (iÅŸleme içermeyen dal) içeren\n" +"bir çalışma aÄŸacı oluÅŸturmak istediyseniz bunu --orphan bayrağını\n" +"kullanarak yapabilirsiniz:\n" "\n" " git worktree add --orphan -b %s %s\n" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan %s\n" msgstr "" -"Bu depo için yeni bir yetim dal içeren (iÅŸlemesiz dal) bir\n" -"çalışma aÄŸacı oluÅŸturmak istediyseniz bunu --orphan bayrağı\n" -"ile yapabilirsiniz:\n" +"Bu depo için henüz doÄŸmamış bir dal (iÅŸleme içermeyen dal) içeren\n" +"bir çalışma aÄŸacı oluÅŸturmak istediyseniz bunu --orphan bayrağını\n" +"kullanarak yapabilirsiniz:\n" "\n" " git worktree add --orphan %s\n" @@ -13378,6 +13526,10 @@ msgid "initializing" msgstr "ilklendiriliyor" #, c-format +msgid "could not find created worktree '%s'" +msgstr "oluÅŸturulan '%s' çalışma aÄŸacı bulunamadı" + +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "Çalışma aÄŸacı hazırlanıyor (yeni dal '%s')" @@ -13409,15 +13561,10 @@ msgstr "" msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" -"Bir uzak konum olmasına raÄŸmen hiçbir yerel veya uzak baÅŸvuru\n" -"yok, durduruluyor; geçersiz kılmak için 'add -f' kullanın veya\n" -"önce bir uzak konum getirin" - -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "'%s' ve '%s' birlikte kullanılamaz" +"Bir uzak konum olmasına raÄŸmen hiçbir yerel/uzak baÅŸvuru yok, durduruluyor;\n" +"geçersiz kılmak veya önce bir uzak konum getirmek için 'add -f' kullanın" msgid "checkout <branch> even if already checked out in other worktree" msgstr "diÄŸer çalışma aÄŸacında çıkış yapılmış olsa bile <dal> çıkışını yap" @@ -13428,8 +13575,8 @@ msgstr "yeni bir dal oluÅŸtur" msgid "create or reset a branch" msgstr "yeni bir dal oluÅŸtur veya sıfırla" -msgid "create unborn/orphaned branch" -msgstr "doÄŸmamış/yetim bırakılmış dal oluÅŸtur" +msgid "create unborn branch" +msgstr "henüz doÄŸmamış dal oluÅŸtur" msgid "populate the new working tree" msgstr "yeni çalışma aÄŸacını doldur" @@ -13451,11 +13598,8 @@ msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "'%s', '%s' ve '%s' seçenekleri birlikte kullanılamaz" #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "'%s' ve '%s' seçenekleri birlikte kullanılamaz" - -msgid "<commit-ish>" -msgstr "<iÅŸlememsi>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "'%s' seçeneÄŸi ve iÅŸlememsiler birlikte kullanılamaz" msgid "added with --lock" msgstr "--lock ile eklendi" @@ -13727,6 +13871,10 @@ msgid "terminating chunk id appears earlier than expected" msgstr "iri parça numarası sonlandırması beklenenden önce ortaya çıkıyor" #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "iri parça kimliÄŸi %<PRIx32>, %d bayt hizalı deÄŸil" + +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "düzgün olmayan iri parça ofseti %<PRIx64> ve %<PRIx64>" @@ -13778,8 +13926,8 @@ msgstr "Hata raporu bildirimi için veri topla" msgid "Move objects and refs by archive" msgstr "Nesneleri ve baÅŸvuruları arÅŸive göre taşı" -msgid "Provide content or type and size information for repository objects" -msgstr "Depo nesneleri için içerik veya tür/boyut bilgisi saÄŸla" +msgid "Provide contents or details of repository objects" +msgstr "Depo nesnelerinin içeriÄŸini veya ayrıntılarını saÄŸla" msgid "Display gitattributes information" msgstr "gitattributes bilgisini görüntüle" @@ -14063,6 +14211,10 @@ msgstr "Bir depodaki paketlenmemiÅŸ nesneleri paketle" msgid "Create, list, delete refs to replace objects" msgstr "Nesne deÄŸiÅŸtirmek için baÅŸvurular oluÅŸtur, sil, listele" +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "" +"DENEYSEL: İşlemeleri yeni temelde yeniden oynat, çıplak depolarla da çalışır" + msgid "Generates a summary of pending changes" msgstr "Bekleyen deÄŸiÅŸikliklerin bir özetini çıkart" @@ -14184,8 +14336,8 @@ msgstr "Etiketlerin GPG imzasını doÄŸrula" msgid "Display version information about Git" msgstr "Git sürüm bilgisini görüntüle" -msgid "Show logs with difference each commit introduces" -msgstr "Günlükleri her iÅŸlemenin sunduÄŸu deÄŸiÅŸikliklerle göster" +msgid "Show logs with differences each commit introduces" +msgstr "Günlükleri her iÅŸlemenin deÄŸiÅŸiklikleriyle göster" msgid "Manage multiple working trees" msgstr "Birden çok çalışma aÄŸacını yönet" @@ -14301,6 +14453,32 @@ msgstr "Büyük Git depolarını yönetmek için bir araç" msgid "commit-graph file is too small" msgstr "commit-graph dosyası pek küçük" +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "commit-graph OID çıkış sayısı iri parçası boyutu yanlış" + +msgid "commit-graph fanout values out of order" +msgstr "commit-graph çıkış sayısı deÄŸerleri sırasız: fanout[%d] = %u != %u" + +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "commit-graph OID arama iri parçası boyutu yanlış" + +msgid "commit-graph commit data chunk is wrong size" +msgstr "commit-graph iÅŸleme verisi iri parçası boyutu yanlış" + +msgid "commit-graph generations chunk is wrong size" +msgstr "commit-graph kuÅŸaklar iri parçası boyutu yanlış" + +msgid "commit-graph changed-path index chunk is too small" +msgstr "commit-graph changed-path indeksi iri parçası boyutu pek küçük" + +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "" +"commit-graph dosyasındaki pek küçük changed-path iri parçası (%<PRIuMAX> < " +"%<PRIuMAX>) yok sayılıyor" + #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "commit-graph imzası %X, %X ile eÅŸleÅŸmiyor" @@ -14317,9 +14495,23 @@ msgstr "commit-graph saÄŸlama sürümü %X, %X ile eÅŸleÅŸmiyor" msgid "commit-graph file is too small to hold %u chunks" msgstr "commit-graph dosyası %u iri parça tutmak için pek küçük" +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "" +"commit-graph'ten gerekli OID çıkış sayısı iri parçası eksik veya hasarlı" + +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "commit-graph'ten gerekli OID arama iri parçası eksik veya hasarlı" + +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "" +"commit-graph'ten gerekli OID çıkış sayısı iri parçası eksik veya hasarlı" + msgid "commit-graph has no base graphs chunk" msgstr "commit-graph temel grafiÄŸi iri parçasına iye deÄŸil" +msgid "commit-graph base graphs chunk is too small" +msgstr "commit-graph temel grafiÄŸi iri parçası pek küçük" + msgid "commit-graph chain does not match" msgstr "commit-graph zinciri eÅŸleÅŸmiyor" @@ -14327,6 +14519,9 @@ msgstr "commit-graph zinciri eÅŸleÅŸmiyor" msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "temel grafikteki iÅŸleme sayısı pek yüksek: %<PRIuMAX>" +msgid "commit-graph chain file too small" +msgstr "commit-graph zincir dosyası pek küçük" + #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" msgstr "geçersiz commit-graph zinciri: '%s'. satır bir saÄŸlama deÄŸil" @@ -14344,6 +14539,12 @@ msgstr "%s iÅŸlemesi bulunamadı" msgid "commit-graph requires overflow generation data but has none" msgstr "commit-graph, taşım oluÅŸturma verisi gerektiriyor; ancak hiç yok" +msgid "commit-graph overflow generation data is too small" +msgstr "commit-graph, taşım üretim verisi pek küçük" + +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "commit-graph extra-edges iÅŸaretçisi sınırlar dışında" + msgid "Loading known commits in commit graph" msgstr "İşleme grafiÄŸindeki bilinen iÅŸlemeler yükleniyor" @@ -14471,20 +14672,6 @@ msgid "commit-graph parent list for commit %s terminates early" msgstr "%s iÅŸlemesi için olan commit-graph üst öge listesi erkenden sonlanıyor" #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" -"%s iÅŸlemesi için commit-graph kuÅŸak sayısı sıfır; ancak baÅŸka yerlerde " -"sıfırdan farklı" - -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" -"%s iÅŸlemesi için commit-graph kuÅŸak sayısı sıfırdan farklı; ancak baÅŸka " -"yerlerde sıfır" - -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "%s iÅŸlemesi için commit-graph kuÅŸağı %<PRIuMAX> < %<PRIuMAX>" @@ -14493,6 +14680,14 @@ msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>" msgstr "" "%s iÅŸlemesi için commit-graph içindeki iÅŸleme tarihi %<PRIuMAX> != %<PRIuMAX>" +#, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "" +"commit-graph'te hem sıfır hem de sıfır olmayan üretimler var (örneÄŸin, " +"'%s've '%s' iÅŸlemeleri)" + msgid "Verifying commits in commit graph" msgstr "İşleme grafiÄŸindeki iÅŸlemeler doÄŸrulanıyor" @@ -14520,6 +14715,10 @@ msgstr "" "kullanarak bu iletiyi kapatabilirsiniz" #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "%s iÅŸlemesi iÅŸleme grafiÄŸinde var; ancak nesne veritabanında yok" + +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "" "%s iÅŸlemesinin güvenilmeyen bir GPG imzası var, iddiaya göre %s tarafından." @@ -14960,10 +15159,6 @@ msgstr "'%s' baÅŸvurusu ikili bir nesneye iÅŸaret etmiyor" msgid "unable to resolve config blob '%s'" msgstr "'%s' yapılandırma ikili nesnesi çözülemiyor" -#, c-format -msgid "failed to parse %s" -msgstr "%s ayrıştırılamadı" - msgid "unable to parse command-line config" msgstr "komut satırı yapılandırması ayrıştırılamıyor" @@ -15431,9 +15626,6 @@ msgstr "arÅŸiv yazılamadı" msgid "--merge-base does not work with ranges" msgstr "--merge-base erimlerle çalışmaz" -msgid "--merge-base only works with commits" -msgstr "--merge-base yalnızca iÅŸlemelerle çalışır" - msgid "unable to get HEAD" msgstr "HEAD alınamıyor" @@ -15494,6 +15686,10 @@ msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "'diff.submodule' yapılandırma deÄŸiÅŸkeni için bilinmeyen deÄŸer: '%s'" #, c-format +msgid "unknown value for config '%s': %s" +msgstr "'%s' yapılandırması için bilinmeyen deÄŸer: %s" + +#, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" @@ -15573,13 +15769,6 @@ msgstr "hatalı --color-moved argümanı: %s" msgid "invalid mode '%s' in --color-moved-ws" msgstr "--color-moved-ws içinde geçersiz kip '%s'" -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"diff-algorithm seçeneÄŸi ÅŸunları kabul eder: \"myers\", \"minimal\", " -"\"patience\" ve \"histogram\"" - #, c-format msgid "invalid argument to %s" msgstr "%s için geçersiz argüman" @@ -15623,8 +15812,8 @@ msgstr "makinede okunabilen --stat" msgid "output only the last line of --stat" msgstr "--stat'ın yalnızca son satırını çıktı ver" -msgid "<param1,param2>..." -msgstr "<param1,param2>..." +msgid "<param1>,<param2>..." +msgstr "<param1>,<param2>..." msgid "" "output the distribution of relative amount of changes for each sub-directory" @@ -15634,8 +15823,8 @@ msgstr "" msgid "synonym for --dirstat=cumulative" msgstr "--dirstat=cumulative eÅŸanlamlısı" -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "--dirstat=files,param1,param2... eÅŸanlamlısı" +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "--dirstat=files,<param1>,<param2>... eÅŸanlamlısı" msgid "warn if changes introduce conflict markers or whitespace errors" msgstr "" @@ -15810,12 +15999,6 @@ msgstr "diff'i \"patience diff\" algoritmasını kullanarak oluÅŸtur" msgid "generate diff using the \"histogram diff\" algorithm" msgstr "diff'i \"histogram diff\" algoritmasını kullanarak oluÅŸtur" -msgid "<algorithm>" -msgstr "<algoritma>" - -msgid "choose a diff algorithm" -msgstr "bir diff algoritması seç" - msgid "<text>" msgstr "<metin>" @@ -16849,12 +17032,12 @@ msgstr "" "%s altmodülü birleÅŸtirilemedi; ancak birden çok olası birleÅŸtirmeler var:\n" "%s" -msgid "Failed to execute internal merge" -msgstr "İç birleÅŸtirme yürütülemedi" +msgid "failed to execute internal merge" +msgstr "iç birleÅŸtirme yürütülemedi" #, c-format -msgid "Unable to add %s to database" -msgstr "%s veritabanına eklenemedi" +msgid "unable to add %s to database" +msgstr "%s veritabanına eklenemiyor" #, c-format msgid "Auto-merging %s" @@ -17298,7 +17481,19 @@ msgid "failed to read the cache" msgstr "önbellek okunamadı" msgid "multi-pack-index OID fanout is of the wrong size" -msgstr "multi-pack-index OID ikiye bölümünün boyutu hatalı" +msgstr "multi-pack-index OID çıkış sayısı boyutu yanlış" + +#, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"oid çıkış sayısı sırasız: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" + +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "multi-pack-index OID arama iri parçası yanlış boyutlu" + +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "multi-pack-index OID nesne ofseti iri parçası yanlış boyutlu" #, c-format msgid "multi-pack-index file %s is too small" @@ -17316,17 +17511,21 @@ msgstr "multi-pack-index sürümü %d tanımlanamıyor" msgid "multi-pack-index hash version %u does not match version %u" msgstr "multi-pack-index saÄŸlama sürümü %u, %u sürümü ile eÅŸleÅŸmiyor" -msgid "multi-pack-index missing required pack-name chunk" -msgstr "multi-pack-index'ten gerekli pack-name iri parçası eksik" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "multi-pack-index'ten gerekli pack-name iri parçası eksik veya hasarlı" -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "multi-pack-index'ten gerekli OID fanout iri parçası eksik" +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "multi-pack-index'ten gerekli OID fanout iri parçası eksik veya hasarlı" -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "multi-pack-index'ten gerekli OID arama iri parçası eksik" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "multi-pack-index'ten gerekli OID arama iri parçası eksik veya hasarlı" -msgid "multi-pack-index missing required object offsets chunk" -msgstr "multi-pack-index'ten gerekli nesne ofsetleri iri parçası eksik" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "" +"multi-pack-index'ten gerekli nesne ofsetleri iri parçası eksik veya hasarlı" + +msgid "multi-pack-index pack-name chunk is too short" +msgstr "multi-pack-index pack-name iri parçası pek kısa" #, c-format msgid "multi-pack-index pack names out of order: '%s' before '%s'" @@ -17336,9 +17535,19 @@ msgstr "multi-pack-index paket adlarının sırasız: '%s' ÅŸundan önce: '%s'" msgid "bad pack-int-id: %u (%u total packs)" msgstr "hatalı pack-int-id: %u (%u toplam paket)" +msgid "MIDX does not contain the BTMP chunk" +msgstr "MIDX, BTMP iri parçasını içermiyor" + +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "biteÅŸlemli %<PRIu32> paketi yüklenemedi" + msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "multi-pack-index bir 64 bit ofset depoluyor; ancak off_t pek küçük" +msgid "multi-pack-index large offset out of bounds" +msgstr "multi-pack-index geniÅŸ ofseti sınırlar dışında" + #, c-format msgid "failed to add packfile '%s'" msgstr "paket dosyası '%s' eklenemedi" @@ -17416,11 +17625,6 @@ msgstr "yanlış saÄŸlama toplamı" msgid "Looking for referenced packfiles" msgstr "BaÅŸvurulmuÅŸ paket dosyaları aranıyor" -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "oid fanout sırasız: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" - msgid "the midx contains no oid" msgstr "midx bir oid içermiyor" @@ -17940,9 +18144,12 @@ msgstr "çoklu paket biteÅŸlemi gereken ters indeksi içermiyor" msgid "could not open pack %s" msgstr "%s paketi açılamadı" +msgid "could not determine MIDX preferred pack" +msgstr "MIDX yeÄŸlenen paketi algılanamadı" + #, c-format msgid "preferred pack (%s) is invalid" -msgstr "tercih edilen (%s) paket geçersiz" +msgstr "yeÄŸlenen paket (%s) geçersiz" msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "hasarlı biteÅŸlem arama tablosu: üçlü konum indeks dışında" @@ -17960,6 +18167,10 @@ msgstr "" "hasarlı ewah biteÅŸlemi: \"%s\" iÅŸlemesinin biteÅŸleminde kısaltılmış üstbilgi" #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "paket yüklenemiyor: '%s', pack-reuse devre dışı bırakılıyor" + +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "'%s' nesnesi, tür biteÅŸlemlerinde bulunamadı" @@ -18047,6 +18258,12 @@ msgstr "geçersiz saÄŸlama toplamı" msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "%<PRIu64> konumunda geçersiz rev-index konumu: %<PRIu32> != %<PRIu32>" +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "multi-pack-index reverse-index iri parçası yanlış boyutlu" + +msgid "could not determine preferred pack" +msgstr "yeÄŸlenen paket algılanamadı" + msgid "cannot both write and verify reverse index" msgstr "ters indeks dosyası hem yazılıp hem doÄŸrulanamıyor" @@ -18098,14 +18315,6 @@ msgid "%s requires a value" msgstr "%s bir deÄŸer gerektiriyor" #, c-format -msgid "%s is incompatible with %s" -msgstr "%s, %s ile uyumsuz" - -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s: baÅŸka bir ÅŸeyle uyumsuz" - -#, c-format msgid "%s takes no value" msgstr "%s bir deÄŸer almıyor" @@ -18188,6 +18397,10 @@ msgstr " %s" msgid "-NUM" msgstr "-SAYI" +#, c-format +msgid "opposite of --no-%s" +msgstr "--no-%s karşıtı" + msgid "expiry-date" msgstr "son kullanım tarihi" @@ -18215,7 +18428,15 @@ msgstr "yol belirtecini dosyadan oku" msgid "" "with --pathspec-from-file, pathspec elements are separated with NUL character" msgstr "" -"--pathspec-from-file ile, yol belirteci ögeleri NUL karakteri ile ayrılır" +"--pathspec-from-file ile yol belirteci ögeleri NUL karakteri ile ayrılır" + +#, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "hatalı Boole çevre deÄŸeri '%s', '%s' için" + +#, c-format +msgid "failed to parse %s" +msgstr "%s ayrıştırılamadı" #, c-format msgid "Could not make %s writable by group" @@ -18264,6 +18485,10 @@ msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s: 'literal' ve 'glob' birbiriyle uyumsuz" #, c-format +msgid "'%s' is outside the directory tree" +msgstr "'%s', dizin aÄŸacının dışında" + +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s: '%s', '%s' konumunda depo dışında" @@ -18415,10 +18640,6 @@ msgid "unable to add '%s' to index" msgstr "'%s' indekse eklenemiyor" #, c-format -msgid "unable to stat '%s'" -msgstr "'%s' dosyasının bilgileri alınamıyor" - -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "'%s' hem bir dosya hem de bir dizin olarak görünüyor" @@ -18526,10 +18747,6 @@ msgid "failed to convert to a sparse-index" msgstr "bir sparse-index'e dönüştürülemedi" #, c-format -msgid "could not stat '%s'" -msgstr "'%s' bilgileri alınamadı" - -#, c-format msgid "unable to open git dir: %s" msgstr "git dizini açılamıyor: %s" @@ -18994,10 +19211,6 @@ msgid "cannot process '%s' and '%s' at the same time" msgstr "'%s' ve '%s' aynı anda iÅŸlenemiyor" #, c-format -msgid "could not remove reference %s" -msgstr "%s baÅŸvurusu kaldırılamadı" - -#, c-format msgid "could not delete reference %s: %s" msgstr "%s baÅŸvurusu silinemedi: %s" @@ -19551,8 +19764,15 @@ msgstr "klonlama sırasında tam çalışma dizini oluÅŸtur" msgid "only download metadata for the branch that will be checked out" msgstr "yalnızca çıkış yapılacak dalın üstverisini indir" -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [<seçenekler>] [--] <depo> [<dizin>]" +msgid "create repository within 'src' directory" +msgstr "'src' dizininde depo oluÅŸtur" + +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <ana-dal>] [--full-clone]\n" +"\t[--[no-]src] <url> [<yazılma>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -19603,12 +19823,28 @@ msgid "could not remove stale scalar.repo '%s'" msgstr "eskimiÅŸ scalar.repo '%s' kaldırılamadı" #, c-format -msgid "removing stale scalar.repo '%s'" -msgstr "eskimiÅŸ scalar.repo '%s' kaldırılıyor" +msgid "removed stale scalar.repo '%s'" +msgstr "eskimiÅŸ scalar.repo '%s' kaldırıldı" #, c-format -msgid "git repository gone in '%s'" -msgstr "git deposu '%s' içinde gitti" +msgid "repository at '%s' has different owner" +msgstr "'%s' konumundaki deponun sahibi baÅŸkası" + +#, c-format +msgid "repository at '%s' has a format issue" +msgstr "'%s' konumundaki depoda bir biçim sorunu var" + +#, c-format +msgid "repository not found in '%s'" +msgstr "'%s' konumunda depo bulunamadı" + +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"bu deponun kaydını Scalar'dan kaldırmak için ÅŸu komutu çalıştırın:\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" msgid "" "scalar run <task> [<enlistment>]\n" @@ -20009,10 +20245,6 @@ msgid "%s: cannot parse parent commit %s" msgstr "%s: üst iÅŸleme %s ayrıştırılamıyor" #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "'%s', '%s' olarak yeniden adlandırılamadı" - -#, c-format msgid "could not revert %s... %s" msgstr "%s geri alınamadı... %s" @@ -20334,6 +20566,9 @@ msgstr "KendiliÄŸinden zulalama çakışmalara neden oldu." msgid "Autostash exists; creating a new stash entry." msgstr "KendiliÄŸinden zulalama mevcut; yeni bir zula girdisi oluÅŸturuluyor." +msgid "autostash reference is a symref" +msgstr "kendiliÄŸinden zulalama baÅŸvurusu bir sembol baÅŸvurusu" + msgid "could not detach HEAD" msgstr "HEAD ayrılamadı" @@ -20366,14 +20601,14 @@ msgstr "" "\tgit rebase --continue\n" #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "Yeniden temellendiriliyor: (%d/%d)%s" - -#, c-format msgid "Stopped at %s... %.*s\n" msgstr "%s konumunda durdu... %.*s\n" #, c-format +msgid "Rebasing (%d/%d)%s" +msgstr "Yeniden temellendiriliyor: (%d/%d)%s" + +#, c-format msgid "unknown command %d" msgstr "bilinmeyen komut %d" @@ -20645,6 +20880,10 @@ msgid "invalid initial branch name: '%s'" msgstr "geçersiz baÅŸlangıç dalı adı: '%s'" #, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "re-init: --initial-branch=%s yok sayıldı" + +#, c-format msgid "unable to handle file type %d" msgstr "%d dosya türü ele alınamıyor" @@ -20655,15 +20894,16 @@ msgstr "%s ÅŸuraya taşınamıyor: %s" msgid "attempt to reinitialize repository with different hash" msgstr "depoyu baÅŸka bir saÄŸlama ile yeniden ilklendirme deneniyor" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "" +"depo baÅŸka bir baÅŸvuru depolama biçimiyle yeniden ilklendirilmeye çalışılıyor" + #, c-format msgid "%s already exists" msgstr "%s halihazırda var" #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "re-init: --initial-branch=%s yok sayıldı" - -#, c-format msgid "Reinitialized existing shared Git repository in %s%s\n" msgstr "%s%s içindeki var olan paylaşılan Git deposu yeniden ilklendirildi\n" @@ -20927,12 +21167,6 @@ msgstr "her bir yinelemeden önce önbellek aÄŸacını temizle" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "önbellek aÄŸacındaki geçersizleÅŸtirilecek girdi sayısı (öntanımlı 0)" -msgid "unhandled options" -msgstr "beklenmeyen seçenekler" - -msgid "error preparing revisions" -msgstr "revizyonlar hazırlanırken hata" - #, c-format msgid "commit %s is not marked reachable" msgstr "%s iÅŸlemesi ulaşılabilir olarak imlenmedi" @@ -21086,9 +21320,6 @@ msgstr "uzak servis yolu ayarlama protokol tarafından desteklenmiyor" msgid "invalid remote service path" msgstr "geçersiz uzak konum servis yolu" -msgid "operation not supported by protocol" -msgstr "iÅŸlem protokol tarafından desteklenmiyor" - #, c-format msgid "can't connect to subservice %s" msgstr "%s altservisine baÄŸlanılamıyor" @@ -21219,10 +21450,6 @@ msgid "support for protocol v2 not implemented yet" msgstr "protokol v2 desteÄŸi henüz yerine getirilmedi" #, c-format -msgid "unknown value for config '%s': %s" -msgstr "'%s' yapılandırması için bilinmeyen deÄŸer: %s" - -#, c-format msgid "transport '%s' not allowed" msgstr "'%s' taşıyıcısına izin verilmiyor" @@ -21275,6 +21502,9 @@ msgstr "bundle-uri iÅŸlemi protokol tarafından desteklenmiyor" msgid "could not retrieve server-advertised bundle-uri list" msgstr "sunucu tarafından tanıtılan bundle-uri listesi alınamadı" +msgid "operation not supported by protocol" +msgstr "iÅŸlem protokol tarafından desteklenmiyor" + msgid "too-short tree object" msgstr "aÄŸaç nesnesi çok kısa" @@ -21661,6 +21891,9 @@ msgstr "'%s' eriÅŸilemiyor" msgid "unable to get current working directory" msgstr "geçerli çalışma dizini alınamıyor" +msgid "unable to get random bytes" +msgstr "rastgele baytlar alınamıyor" + msgid "Unmerged paths:" msgstr "BirleÅŸtirilmemiÅŸ yollar:" @@ -22095,6 +22328,10 @@ msgstr "Ek olarak, indeksiniz iÅŸlenmemiÅŸ deÄŸiÅŸiklikler içeriyor." msgid "cannot %s: Your index contains uncommitted changes." msgstr "%s yapılamıyor: İndeksiniz iÅŸlenmemiÅŸ deÄŸiÅŸiklikler içeriyor." +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "'%s' bilinmeyen biçemi ÅŸunun için verildi: '%s'" + msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" @@ -22277,13 +22514,13 @@ msgstr "" "Bir özet göndermek istemiyorsanız gövde kısmını temizleyin.\n" #, perl-format -msgid "Failed to open %s: %s" -msgstr "%s açılamadı: %s" - -#, perl-format msgid "Failed to open %s.final: %s" msgstr "%s.final açılamadı: %s" +#, perl-format +msgid "Failed to open %s: %s" +msgstr "%s açılamadı: %s" + msgid "Summary email is empty, skipping it\n" msgstr "Özet e-postası boÅŸ, atlanıyor\n" @@ -6,10 +6,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Git v2.42.0\n" +"Project-Id-Version: Git v2.43\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-15 15:28-0700\n" -"PO-Revision-Date: 2023-08-15 15:31-0700\n" +"POT-Creation-Date: 2023-11-09 14:26-0800\n" +"PO-Revision-Date: 2024-02-11 09:26-0800\n" "Last-Translator: Arkadii Yakovets <ark@cho.red>\n" "Language-Team: Ukrainian <https://github.com/arkid15r/git-uk-l10n/>\n" "Language: uk\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" -"X-Generator: Poedit 3.3.2\n" +"X-Generator: Poedit 3.4.2\n" #, c-format msgid "Huh (%s)?" @@ -525,7 +525,6 @@ msgstr "\"git apply --cached\" завершивÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾" #. (saying "n" for "no" discards!) if the translation #. of the word "no" does not start with n. #. - msgid "" "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? " msgstr "" @@ -1445,6 +1444,10 @@ msgid "Unexpected option --output" msgstr "Ðеочікувана Ð¾Ð¿Ñ†Ñ–Ñ --output" #, c-format +msgid "extra command line parameter '%s'" +msgstr "зайвий параметр командного Ñ€Ñдка: \"%s\"" + +#, c-format msgid "Unknown archive format '%s'" msgstr "Ðевідомий формат архіву \"%s\"" @@ -1490,6 +1493,14 @@ msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "невірний --attr-source або GIT_ATTR_SOURCE" #, c-format +msgid "unable to stat '%s'" +msgstr "не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ stat Ð´Ð»Ñ \"%s\"" + +#, c-format +msgid "unable to read %s" +msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ %s" + +#, c-format msgid "Badly quoted content in file '%s': %s" msgstr "Ðевірно процитований вміÑÑ‚ у файлі \"%s\": %s" @@ -1587,7 +1598,6 @@ msgstr[2] "(приблизно %d кроків)" #. TRANSLATORS: the last %s will be replaced with "(roughly %d #. steps)" translation. #. - #, 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" @@ -1668,16 +1678,17 @@ msgstr "" msgid "not tracking: ambiguous information for ref '%s'" msgstr "не відÑтежуєтьÑÑ: неоднозначна Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð´Ð»Ñ Ð¿Ð¾ÑÐ¸Ð»Ð°Ð½Ð½Ñ \"%s\"" +#. #-#-#-#-# branch.c.po #-#-#-#-# #. TRANSLATORS: This is a line listing a remote with duplicate #. refspecs in the advice message below. For RTL languages you'll #. probably want to swap the "%s" and leading " " space around. #. +#. #-#-#-#-# object-name.c.po #-#-#-#-# #. TRANSLATORS: This is line item of ambiguous object output #. from describe_ambiguous_object() above. For RTL languages #. you'll probably want to swap the "%s" and leading " " space #. around. #. - #, c-format msgid " %s\n" msgstr " %s\n" @@ -1685,7 +1696,6 @@ msgstr " %s\n" #. TRANSLATORS: The second argument is a \n-delimited list of #. duplicate refspecs, composed above. #. - #, c-format msgid "" "There are multiple remotes whose fetch refspecs map to the remote\n" @@ -1781,8 +1791,8 @@ msgid "submodule '%s': cannot create branch '%s'" msgstr "підмодуль \"%s\": неможливо Ñтворити гілку \"%s\"" #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "\"%s\" вже Ñ–Ñнує в \"%s\"" +msgid "'%s' is already used by worktree at '%s'" +msgstr "\"%s\" вже викориÑтовуєтьÑÑ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ð¼ деревом в \"%s\"" msgid "git add [<options>] [--] <pathspec>..." msgstr "git add [<опції>] [--] <визначник шлÑху>..." @@ -1801,25 +1811,22 @@ msgstr "" "параметр add.interactive.useBuiltin було видалено!\n" "ДивітьÑÑ Ð·Ð°Ð¿Ð¸Ñ Ñƒ \"git help config\" Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ детальної інформації." -msgid "Could not read the index" -msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ індекÑ" - -msgid "Could not write patch" -msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати латку" +msgid "could not read the index" +msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ індекÑ" msgid "editing patch failed" msgstr "не вдалоÑÑ Ð²Ñ–Ð´Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ латку" #, c-format -msgid "Could not stat '%s'" -msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ stat \"%s\"" +msgid "could not stat '%s'" +msgstr "не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ stat \"%s\"" -msgid "Empty patch. Aborted." -msgstr "ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð»Ð°Ñ‚ÐºÐ°. Перервано." +msgid "empty patch. aborted" +msgstr "Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ Ð»Ð°Ñ‚ÐºÐ°. перервано" #, c-format -msgid "Could not apply '%s'" -msgstr "Ðе вдалоÑÑ Ð·Ð°ÑтоÑувати \"%s\"" +msgid "could not apply '%s'" +msgstr "не вдалоÑÑ Ð·Ð°ÑтоÑувати \"%s\"" msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "ÐаÑтупні шлÑхи ігноруютьÑÑ Ð¾Ð´Ð½Ð¸Ð¼ з ваших .gitignore файлів:\n" @@ -1947,6 +1954,9 @@ msgstr "" msgid "index file corrupt" msgstr "індекÑний файл пошкоджено" +msgid "unable to write new index file" +msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати новий файл індекÑу" + #, c-format msgid "bad action '%s' for '%s'" msgstr "невірна Ð´Ñ–Ñ \"%s\" Ð´Ð»Ñ \"%s\"" @@ -2094,7 +2104,6 @@ msgstr "Тіло коміту:" #. in your translation. The program will only accept English #. input at this point. #. - #, c-format msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: " msgstr "" @@ -2158,9 +2167,6 @@ msgstr "" "щоб позначити Ñ—Ñ… Ñк такі.\n" "Ви можете виконати \"git rm\" Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñƒ, щоб прийнÑти \"видалено ними\"." -msgid "unable to write new index file" -msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати новий файл індекÑу" - #, c-format msgid "Could not parse object '%s'." msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ об'єкт '%s'." @@ -2179,10 +2185,6 @@ msgstr "" msgid "failed to read '%s'" msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ \"%s\"" -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "опції \"%s=%s\" and \"%s=%s\" не можна викориÑтовувати разом" - msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<опції>] [(<Ñкринька> [<поштова директоріÑ>)...]" @@ -2334,10 +2336,10 @@ msgid "git archive: expected a flush" msgstr "git archive: очікувалоÑÑŒ flush" msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=<термін> --term-{old,good}=<термін>] " +"git bisect start [--term-(new,bad)=<термін> --term-(old,good)=<термін>] " "[--no-checkout] [--first-parent] [<поганий> [<добрий>...]] [--] " "[<визначник шлÑху>...]" @@ -2353,8 +2355,8 @@ msgstr "git bisect reset [<коміт>]" msgid "git bisect replay <logfile>" msgstr "git bisect replay <лог файл>" -msgid "git bisect run <cmd>..." -msgstr "git bisect run <команда>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <команда> [<аргумент>...]" #, c-format msgid "cannot open file '%s' in mode '%s'" @@ -2442,7 +2444,6 @@ msgstr "біÑÐµÐºÑ†Ñ–Ñ Ð»Ð¸ÑˆÐµ з %s комітом" #. translation. The program will only accept English input #. at this point. #. - msgid "Are you sure [Y/n]? " msgstr "Ви впевнені [Y/n]? " @@ -2519,7 +2520,6 @@ msgstr "Вам потрібно почати з \"git bisect start\"\n" #. translation. The program will only accept English input #. at this point. #. - msgid "Do you want me to do it for you [Y/n]? " msgstr "Ви хочете, щоб Ñ Ð·Ñ€Ð¾Ð±Ð¸Ð² це Ð´Ð»Ñ Ð²Ð°Ñ [Y/n]? " @@ -2737,7 +2737,6 @@ msgstr "" #. your language may need more or fewer display #. columns. #. - msgid "4 years, 11 months ago" msgstr "4 роки, 11 міÑÑців тому" @@ -2782,44 +2781,47 @@ msgstr "git branch [<опції>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" "Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð³Ñ–Ð»ÐºÐ¸ \"%s\", Ñка була злита з\n" -" \"%s\", але ще не злита з HEAD." +" \"%s\", але ще не злита з HEAD" #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" "ÑƒÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð³Ñ–Ð»ÐºÐ¸ \"%s\", Ñка ще не була злита з\n" -" \"%s\", незважаючи на те, що вже злита з HEAD." +" \"%s\", незважаючи на те, що вже була злита з HEAD" #, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ об’єкт коміту Ð´Ð»Ñ \"%s\"" +msgid "couldn't look up commit object for '%s'" +msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ об’єкт коміту Ð´Ð»Ñ \"%s\"" #, 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'." +msgid "the branch '%s' is not fully merged" +msgstr "гілка \"%s\" злита не повніÑтю" + +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" msgstr "" -"Гілка \"%s\" злита не повніÑтю.\n" -"Якщо ви впевнені, що хочете Ñ—Ñ— видалити, виконайте \"git branch -D %s\"." +"Якщо ви впевнені, що хочете Ñ—Ñ— видалити, виконайте \"git branch -D %s\"" -msgid "Update of config-file failed" -msgstr "Ðе вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ конфігураційний файл" +msgid "update of config-file failed" +msgstr "не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ конфігураційний файл" msgid "cannot use -a with -d" msgstr "не можна викориÑтовувати -a з -d" #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "Ðеможливо видалити гілку \"%s\" за адреÑою \"%s\"" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "" +"неможливо видалити гілку \"%s\", Ñка викориÑтовуєтьÑÑ Ñ€Ð¾Ð±Ð¾Ñ‡Ð¸Ð¼ деревом у " +"\"%s\"" #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "віддалено відÑтежувана гілка \"%s\" не знайдена." +msgid "remote-tracking branch '%s' not found" +msgstr "віддалено відÑтежувана гілка \"%s\" не знайдена" #, c-format msgid "" @@ -2830,8 +2832,8 @@ msgstr "" "Ви забули --remote?" #, c-format -msgid "branch '%s' not found." -msgstr "гілка \"%s\" не знайдена." +msgid "branch '%s' not found" +msgstr "гілка \"%s\" не знайдена" #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" @@ -2852,52 +2854,52 @@ msgid "HEAD (%s) points outside of refs/heads/" msgstr "HEAD (%s) пунктів за межами refs/heads/" #, c-format -msgid "Branch %s is being rebased at %s" -msgstr "Гілка %s перебазуєтьÑÑ Ð½Ð° %s" +msgid "branch %s is being rebased at %s" +msgstr "гілка %s перебазуєтьÑÑ Ð½Ð° %s" #, c-format -msgid "Branch %s is being bisected at %s" -msgstr "Гілка %s біÑектуєтьÑÑ Ð² точці %s" +msgid "branch %s is being bisected at %s" +msgstr "гілка %s біÑектуєтьÑÑ Ð² %s" #, c-format msgid "HEAD of working tree %s is not updated" msgstr "HEAD робочого дерева %s не оновлено" #, c-format -msgid "Invalid branch name: '%s'" -msgstr "ÐеприпуÑтима назва гілки: \"%s\"" +msgid "invalid branch name: '%s'" +msgstr "неприпуÑтима назва гілки: \"%s\"" #, c-format -msgid "No commit on branch '%s' yet." -msgstr "Поки що немає комітів в гілці \"%s\"." +msgid "no commit on branch '%s' yet" +msgstr "поки що немає комітів у гілці \"%s\"" #, c-format -msgid "No branch named '%s'." -msgstr "Ðемає гілки з ім’Ñм \"%s\"." +msgid "no branch named '%s'" +msgstr "немає гілки з назвою \"%s\"" -msgid "Branch rename failed" -msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ гілку" +msgid "branch rename failed" +msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ гілку" -msgid "Branch copy failed" -msgstr "Ðе вдалоÑÑ Ñтворити копію гілки" +msgid "branch copy failed" +msgstr "не вдалоÑÑ Ñкопіювати гілку" #, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "Створено копію невірно названої гілки \"%s\"" +msgid "created a copy of a misnamed branch '%s'" +msgstr "Ñтворено копію невірно названої гілки \"%s\"" #, c-format -msgid "Renamed a misnamed branch '%s' away" -msgstr "Перейменовано невірно названу гілку \"%s\"" +msgid "renamed a misnamed branch '%s' away" +msgstr "перейменовано невірно названу гілку \"%s\"" #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "Гілку перейменовано на %s, але HEAD не оновлено!" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "гілку перейменовано на %s, але HEAD не оновлено" -msgid "Branch is renamed, but update of config-file failed" -msgstr "Гілку перейменовано, але не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ конфігураційний файл" +msgid "branch is renamed, but update of config-file failed" +msgstr "гілку перейменовано, але не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ конфігураційний файл" -msgid "Branch is copied, but update of config-file failed" -msgstr "Гілку Ñкопійовано, але не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ конфігураційний файл" +msgid "branch is copied, but update of config-file failed" +msgstr "гілку Ñкопійовано, але не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ конфігураційний файл" #, c-format msgid "" @@ -3012,8 +3014,8 @@ msgstr "рекурÑивно через підмодулі" msgid "format to use for the output" msgstr "формат, що викориÑтовувати Ð´Ð»Ñ Ð²Ð¸Ð²Ð¾Ð´Ñƒ" -msgid "Failed to resolve HEAD as a valid ref." -msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ñ‚Ð¸ HEAD Ñк дійÑне поÑиланнÑ." +msgid "failed to resolve HEAD as a valid ref" +msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ñ‚Ð¸ HEAD Ñк дійÑне поÑиланнÑ" msgid "HEAD not found below refs/heads!" msgstr "HEAD не знайдено під refs/heads!" @@ -3031,17 +3033,17 @@ msgstr "--recurse-submodules можна викориÑтовувати лише msgid "branch name required" msgstr "назва гілки Ñ” обовʼÑзковою" -msgid "Cannot give description to detached HEAD" -msgstr "Ðеможливо вÑтановити Ð¾Ð¿Ð¸Ñ Ð²Ñ–Ð´Ð¾ÐºÑ€ÐµÐ¼Ð»ÐµÐ½Ð¾Ð¼Ñƒ HEAD" +msgid "cannot give description to detached HEAD" +msgstr "неможливо надати Ð¾Ð¿Ð¸Ñ Ð²Ñ–Ð´Ð¾ÐºÑ€ÐµÐ¼Ð»ÐµÐ½Ð¾Ð¼Ñƒ HEAD" msgid "cannot edit description of more than one branch" msgstr "неможливо редагувати Ð¾Ð¿Ð¸Ñ Ð±Ñ–Ð»ÑŒÑˆ ніж однієї гілки" -msgid "cannot copy the current branch while not on any." -msgstr "неможливо Ñкопіювати поточну гілку, не перебуваючи на жодній з них." +msgid "cannot copy the current branch while not on any" +msgstr "неможливо Ñкопіювати поточну гілку, не перебуваючи на жодній з них" -msgid "cannot rename the current branch while not on any." -msgstr "неможливо перейменувати поточну гілку, не перебуваючи на жодній з них." +msgid "cannot rename the current branch while not on any" +msgstr "неможливо перейменувати поточну гілку, не перебуваючи на жодній з них" msgid "too many branches for a copy operation" msgstr "забагато гілок Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ— копіюваннÑ" @@ -3054,10 +3056,10 @@ msgstr "забагато аргументів Ð´Ð»Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½ #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." +"could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" "не вдалоÑÑ Ð²Ñтановити першождерельне Ñховище HEAD у %s, Ñкий не вказує на " -"жодну гілку." +"жодну гілку" #, c-format msgid "no such branch '%s'" @@ -3070,28 +3072,28 @@ msgstr "гілка \"%s\" не Ñ–Ñнує" msgid "too many arguments to unset upstream" msgstr "забагато аргументів Ð´Ð»Ñ ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð´Ð¶ÐµÑ€ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ Ñховища" -msgid "could not unset upstream of HEAD when it does not point to any branch." +msgid "could not unset upstream of HEAD when it does not point to any branch" msgstr "" -"неможливво Ñкинути Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð´Ð¶ÐµÑ€ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ Ñховища Ð´Ð»Ñ HEAD, Ñкий не " -"вказує на жодну гілку." +"не вдалоÑÑ Ñкинути Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð´Ð¶ÐµÑ€ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ Ñховища Ð´Ð»Ñ HEAD, Ñкий не " +"вказує на жодну гілку" #, c-format -msgid "Branch '%s' has no upstream information" -msgstr "Гілка \"%s\" не має інформації щодо першоджерельного Ñховища" +msgid "branch '%s' has no upstream information" +msgstr "гілка \"%s\" не має інформації щодо першоджерельного Ñховища" msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"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 "" -"Опції -a та -r Ð´Ð»Ñ \"git branch\" не приймають назву гілки.\n" +"опції -a та -r Ð´Ð»Ñ \"git branch\" не приймають назву гілки.\n" "Ви хотіли викориÑтати -a|-r --list <шаблон>?" msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." +"'--set-upstream-to' instead" msgstr "" "Ð¾Ð¿Ñ†Ñ–Ñ \"--set-upstream\" більше не підтримуєтьÑÑ. Будь лаÑка, викориÑтовуйте " -"\"--track\" або \"--set-upstream-to\"." +"\"--track\" або \"--set-upstream-to\" заміÑть неї" msgid "git version:\n" msgstr "верÑÑ–Ñ git:\n" @@ -3167,6 +3169,10 @@ msgid "specify a strftime format suffix for the filename(s)" msgstr "вказати ÑÑƒÑ„Ñ–ÐºÑ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñƒ strftime Ð´Ð»Ñ Ð½Ð°Ð·Ð²Ð¸ файла(-ів)" #, c-format +msgid "unknown argument `%s'" +msgstr "невідомий аргумент \"%s\"" + +#, c-format msgid "could not create leading directories for '%s'" msgstr "не вдалоÑÑ Ñтворити провідні каталоги Ð´Ð»Ñ \"%s\"" @@ -3273,6 +3279,14 @@ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" msgstr "git cat-file (-t | -s) [--allow-unknown-type] <об’єкт>" msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<ревізіÑ>:<шлÑÑ…|деревоподібне-джерело> | --path=<шлÑÑ…|" +"деревоподібне-джерело> <ревізіÑ>]" + +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -3283,14 +3297,6 @@ msgstr "" " [--buffer] [--follow-symlinks] [--unordered]\n" " [--textconv | --filters] [-Z]" -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<ревізіÑ>:<шлÑÑ…|деревоподібне-джерело> | --path=<шлÑÑ…|" -"деревоподібне-джерело> <ревізіÑ>]" - msgid "Check object existence or emit object contents" msgstr "Перевірити Ñ–ÑÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° або видати вміÑÑ‚ об’єкта" @@ -3589,6 +3595,11 @@ msgid "'%s' or '%s' cannot be used with %s" msgstr "\"%s\" або \"%s\" не можна викориÑтовувати з %s" #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "" +"\"%s\", \"%s\" або \"%s\" не можна викориÑтовувати при переключенні Ñтану" + +#, c-format msgid "path '%s' is unmerged" msgstr "шлÑÑ… '%s' не злитий" @@ -3852,8 +3863,8 @@ msgstr "переключити примуÑово (викинути локаль msgid "new-branch" msgstr "нова-гілка" -msgid "new unparented branch" -msgstr "нова гілка без джерела" +msgid "new unborn branch" +msgstr "нова ненароджена гілка" msgid "update ignored files (default)" msgstr "оновити ігноровані файли (за замовчуваннÑм)" @@ -4036,7 +4047,6 @@ msgid "Select items to delete" msgstr "Виберіть елементи Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ" #. TRANSLATORS: Make sure to keep [y/N] as is - #, c-format msgid "Remove %s [y/N]? " msgstr "Видалити %s [y/N]? " @@ -4105,9 +4115,6 @@ msgstr "" "clean.requireForce вÑтановлено у true за замовчуваннÑм Ñ– не задано ні -i, ні " "-n, ні -f; відмовлено в прибиранні" -msgid "-x and -X cannot be used together" -msgstr "-x та -X не можна викориÑтовувати разом" - msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<опції>] [--] <Ñховище> [<директоріÑ>]" @@ -4198,6 +4205,9 @@ msgstr "git директоріÑ" msgid "separate git dir from working tree" msgstr "відокремити git-директорію від робочого дерева" +msgid "specify the reference format to use" +msgstr "вкажіть формат поÑиланнÑ, Ñкий потрібно викориÑтовувати" + msgid "key=value" msgstr "ключ=значеннÑ" @@ -4316,11 +4326,9 @@ msgstr "Забагато аргументів." msgid "You must specify a repository to clone." msgstr "Треба вказати Ñховище Ð´Ð»Ñ ÐºÐ»Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ." -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "" -"--bundle-uri неÑуміÑний з --depth, --shallow-since та --shallow-exclude" +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "невідомий формат Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿Ð¾Ñилань \"%s\"" #, c-format msgid "repository '%s' does not exist" @@ -4455,7 +4463,7 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <директоріÑ>] [--append] [--object-dir " "<директоріÑ>] [--append] [--object-dir <директоріÑ>] [--append\n" @@ -4463,7 +4471,7 @@ msgstr "" "| --stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <чиÑло>] [--" "[no-]progress]\n" -" <опції розділеннÑ>" +" <опції-розділеннÑ>" msgid "dir" msgstr "директоріÑ" @@ -4479,6 +4487,10 @@ msgid "Could not open commit-graph '%s'" msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ коміт-граф \"%s\"" #, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "не вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ ланцюжок коміт-графа \"%s\"" + +#, c-format msgid "unrecognized --split argument, %s" msgstr "нерозпізнаний --split аргумент, %s" @@ -4677,9 +4689,6 @@ msgstr "не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ тимчаÑовий індекÑ" msgid "Failed to update main cache tree" msgstr "Ðе вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ головне дерево кешу" -msgid "unable to write new_index file" -msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати new_index файл" - msgid "cannot do a partial commit during a merge." msgstr "неможливо зробити чаÑтковий коміт під Ñ‡Ð°Ñ Ð·Ð»Ð¸Ñ‚Ñ‚Ñ." @@ -4982,7 +4991,6 @@ msgstr "повторно викориÑтати Ð´Ð¾Ð¿Ð¸Ñ Ð·Ñ– вказаног #. TRANSLATORS: Leave "[(amend|reword):]" as-is, #. and only translate <commit>. #. - msgid "[(amend|reword):]commit" msgstr "[(amend|reword):]коміт" @@ -5081,11 +5089,11 @@ msgstr "ÐŸÐµÑ€ÐµÑ€Ð¸Ð²Ð°Ð½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ через порожнє тіло Ð msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" "Ñховище було оновлено, але не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати\n" -"файл new_index. ПереконайтеÑÑ, що диÑк не переповнений Ñ– квота\n" +"новий файл індекÑу. ПереконайтеÑÑ, що диÑк не переповнений Ñ– квота\n" "не перевищена, а потім виконайте \"git restore --staged :/\" Ð´Ð»Ñ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ." msgid "git config [<options>]" @@ -6194,13 +6202,11 @@ msgid "unknown" msgstr "невідомо" #. TRANSLATORS: e.g. error in tree 01bfda: <more explanation> - #, c-format msgid "error in %s %s: %s" msgstr "помилка в %s %s: %s" #. TRANSLATORS: e.g. warning in tree 01bfda: <more explanation> - #, c-format msgid "warning in %s %s: %s" msgstr "Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ð² %s %s: %s" @@ -6545,6 +6551,9 @@ msgstr "видалити об’єкти, на Ñкі немає поÑÐ¸Ð»Ð°Ð½Ñ msgid "pack unreferenced objects separately" msgstr "пакувати об’єкти, на Ñкі немає поÑилань, окремо" +msgid "with --cruft, limit the size of new cruft packs" +msgstr "з --cruft, обмежити розмір нових марних пакунків" + msgid "be more thorough (increased runtime)" msgstr "працювати ретельніше (збільшує Ñ‡Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ)" @@ -6723,12 +6732,6 @@ msgstr "" msgid "'crontab' died" msgstr "\"crontab\" завершивÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾" -msgid "failed to start systemctl" -msgstr "не вдалоÑÑ Ñтартувати systemctl" - -msgid "failed to run systemctl" -msgstr "не вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити systemctl" - #, c-format msgid "failed to delete '%s'" msgstr "не вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ \"%s\"" @@ -6737,6 +6740,12 @@ msgstr "не вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ \"%s\"" msgid "failed to flush '%s'" msgstr "не вдалоÑÑ Ð¾Ñ‡Ð¸Ñтити \"%s\"" +msgid "failed to start systemctl" +msgstr "не вдалоÑÑ Ñтартувати systemctl" + +msgid "failed to run systemctl" +msgstr "не вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити systemctl" + #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "нерозпізнаний --scheduler аргумент \"%s\"" @@ -6760,6 +6769,9 @@ msgstr "планувальник" msgid "scheduler to trigger git maintenance run" msgstr "планувальник Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑку обÑÐ»ÑƒÐ³Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ git" +msgid "failed to set up maintenance schedule" +msgstr "не вдалоÑÑ Ð²Ñтановити розклад обÑлуговуваннÑ" + msgid "failed to add repo to global config" msgstr "не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ Ñховище до глобальної конфігурації" @@ -6777,11 +6789,11 @@ msgstr "grep: не вдалоÑÑ Ñтворити потік: %s" msgid "invalid number of threads specified (%d) for %s" msgstr "невірно вказана кількіÑть потоків (%d) Ð´Ð»Ñ %s" +#. #-#-#-#-# grep.c.po #-#-#-#-# #. TRANSLATORS: %s is the configuration #. variable for tweaking threads, currently #. grep.threads #. - #, c-format msgid "no threads support, ignoring %s" msgstr "немає підтримки потоків, Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ %s" @@ -6791,6 +6803,10 @@ msgid "unable to read tree (%s)" msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ дерево (%s)" #, c-format +msgid "unable to read tree %s" +msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ дерево %s" + +#, c-format msgid "unable to grep from object of type %s" msgstr "не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ grep Ð´Ð»Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° типу %s" @@ -6834,8 +6850,8 @@ msgstr "оброблÑти бінарні файли за допомогою tex msgid "search in subdirectories (default)" msgstr "шукати в піддиректоріÑÑ… (за замовчуваннÑм)" -msgid "descend at most <depth> levels" -msgstr "ÑпуÑкатиÑÑ Ð½Ðµ більше ніж на <глибина> рівнів" +msgid "descend at most <n> levels" +msgstr "ÑпуÑкатиÑÑ Ð½Ðµ більше ніж на <н> рівнів" msgid "use extended POSIX regular expressions" msgstr "викориÑтовувати розширені POSIX регулÑрні вирази" @@ -7203,10 +7219,6 @@ msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "ВИЯВЛЕÐО SHA1 КОЛІЗІЮ З %s!" #, c-format -msgid "unable to read %s" -msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ %s" - -#, c-format msgid "cannot read existing object info %s" msgstr "неможливо прочитати інформацію про Ñ–Ñнуючий об’єкт %s" @@ -7350,11 +7362,13 @@ msgstr "помилка fsck в об’єктах пакунка" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" "git init [-q | --quiet] [--bare] [--template=<шаблон-директоріÑ>]\n" " [--separate-git-dir <git-директоріÑ>] [--object-format=<формат>]\n" +" [--ref-format=<формат>]\n" " [-b <назва-гілки> | --initial-branch=<назва-гілки>]\n" " [--shared[=<дозволи>]] [<директоріÑ>]" @@ -7398,11 +7412,12 @@ msgstr "--separate-git-dir неÑуміÑна з порожнім Ñховище msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <токен>[(=|:)<значеннÑ>])...]\n" +" [(--trailer <ключ>|" +"<аліаÑКлюча>[(=|:)<значеннÑ>])...]\n" " [--parse] [<файл>...]" msgid "edit files in place" @@ -7411,6 +7426,9 @@ msgstr "редагувати файли на міÑцÑÑ…" msgid "trim empty trailers" msgstr "обрізати порожні причепи" +msgid "placement" +msgstr "розміщеннÑ" + msgid "where to place the new trailer" msgstr "де розміÑтити новий причіп" @@ -7423,17 +7441,17 @@ msgstr "що робити, Ñкщо причіп відÑутній" msgid "output only the trailers" msgstr "виводити лише причепи" -msgid "do not apply config rules" -msgstr "не заÑтоÑовувати правила конфігурації" +msgid "do not apply trailer.* configuration variables" +msgstr "не заÑтоÑовувати конфігураційні змінні trailer.*" -msgid "join whitespace-continued values" -msgstr "об’єднати значеннÑ, що продовжуютьÑÑ Ñ‡ÐµÑ€ÐµÐ· пробіл" +msgid "reformat multiline trailer values as single-line values" +msgstr "переформатувати багаторÑдкові Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ñ‡ÐµÐ¿Ñ–Ð² в однорÑдкові" -msgid "set parsing options" -msgstr "вÑтановити параметри розбору" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "Ð°Ð»Ñ–Ð°Ñ Ð´Ð»Ñ --only-trailers --only-input --unfold" -msgid "do not treat --- specially" -msgstr "не оброблÑти --- оÑобливим чином" +msgid "do not treat \"---\" as the end of input" +msgstr "не оброблÑти \"---\" Ñк кінець вводу" msgid "trailer(s) to add" msgstr "причіп(и) Ð´Ð»Ñ Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ" @@ -7522,6 +7540,10 @@ msgstr "потрібен лишень один діапазон" msgid "not a range" msgstr "не діапазон" +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ файл опиÑу гілки \"%s\"" + msgid "cover letter needs email format" msgstr "Ñупровідний лиÑÑ‚ має бути у форматі електронної пошти" @@ -7622,6 +7644,9 @@ msgstr "cover-from-description-mode" msgid "generate parts of a cover letter based on a branch's description" msgstr "ÑклаÑти чаÑтини Ñупровідного лиÑта на оÑнові опиÑу гілки" +msgid "use branch description from file" +msgstr "викориÑтовувати Ð¾Ð¿Ð¸Ñ Ð³Ñ–Ð»ÐºÐ¸ з файлу" + msgid "use [<prefix>] instead of [PATCH]" msgstr "викориÑтати [<префікÑ>] заміÑть [PATCH]" @@ -7976,7 +8001,6 @@ msgid "--format can't be combined with other format-altering options" msgstr "--format не можна комбінувати з іншими опціÑми зміни формату" #. TRANSLATORS: keep <> in "<" mail ">" info. - msgid "git mailinfo [<options>] <msg> <patch> < mail >info" msgstr "git mailinfo [<опції>] <допиÑ> <латка> < mail >info" @@ -8057,9 +8081,19 @@ msgstr "" "git merge-file [<опції>] [-L <назва1> [-L <оріг> [-L <назва2>]]] <файл1> " "<оріг-файл> <файл2>" +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"Ð¾Ð¿Ñ†Ñ–Ñ diff-algorithm приймає Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \"myers\", \"minimal\", \"patience\" " +"та \"histogram\"" + msgid "send results to standard output" msgstr "надÑилати результати до Ñтандартного виводу" +msgid "use object IDs instead of filenames" +msgstr "викориÑтовувати ідентифікатори обʼєктів заміÑть назв файлів" + msgid "use a diff3 based merge" msgstr "викориÑтовувати Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð½Ð° оÑнові diff3" @@ -8075,6 +8109,12 @@ msgstr "у разі конфліктів викориÑтовувати їхню msgid "for conflicts, use a union version" msgstr "у разі конфліктів викориÑтовувати об’єднану верÑÑ–ÑŽ" +msgid "<algorithm>" +msgstr "<алгоритм>" + +msgid "choose a diff algorithm" +msgstr "вибрати алгоритм різниці" + msgid "for conflicts, use this marker size" msgstr "у разі конфліктів викориÑтовувати цей розмір маркера" @@ -8085,6 +8125,13 @@ msgid "set labels for file1/orig-file/file2" msgstr "вÑтановити мітки Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»1/оріг-файл/файл2" #, c-format +msgid "object '%s' does not exist" +msgstr "об’єкт \"%s\" не Ñ–Ñнує" + +msgid "Could not write object file" +msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати файл обʼєкта" + +#, c-format msgid "unknown option %s" msgstr "невідома Ð¾Ð¿Ñ†Ñ–Ñ %s" @@ -8146,11 +8193,18 @@ msgstr "виконати кілька злиттів, по одному на кРmsgid "specify a merge-base for the merge" msgstr "вказати базу Ð´Ð»Ñ Ð·Ð»Ð¸Ñ‚Ñ‚Ñ" +msgid "option=value" +msgstr "опціÑ=значеннÑ" + +msgid "option for selected merge strategy" +msgstr "Ð¾Ð¿Ñ†Ñ–Ñ Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð½Ð¾Ñ— Ñтратегії злиттÑ" + msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge неÑуміÑна з уÑіма іншими опціÑми" -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base неÑуміÑна з --stdin" +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "невідомий варіант Ñтратегії: -X%s" #, c-format msgid "malformed input line: '%s'." @@ -8219,12 +8273,6 @@ msgstr "ÑтратегіÑ" msgid "merge strategy to use" msgstr "Ñку Ñтратегію Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸Ñтовувати" -msgid "option=value" -msgstr "опціÑ=значеннÑ" - -msgid "option for selected merge strategy" -msgstr "Ð¾Ð¿Ñ†Ñ–Ñ Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð½Ð¾Ñ— Ñтратегії злиттÑ" - msgid "merge commit message (for a non-fast-forward merge)" msgstr "Ð´Ð¾Ð¿Ð¸Ñ Ð´Ð¾ коміту Ð·Ð»Ð¸Ñ‚Ñ‚Ñ (Ð´Ð»Ñ Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð±ÐµÐ· Ð¿ÐµÑ€ÐµÐ¼Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¿ÐµÑ€ÐµÐ´)" @@ -8285,10 +8333,6 @@ msgid "Not handling anything other than two heads merge." msgstr "Ðе оброблюєтьÑÑ Ð½Ñ–Ñ‡Ð¾Ð³Ð¾, окрім Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð´Ð²Ð¾Ñ… верхівок." #, c-format -msgid "unknown strategy option: -X%s" -msgstr "невідомий варіант Ñтратегії: -X%s" - -#, c-format msgid "unable to write %s" msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати %s" @@ -8584,8 +8628,8 @@ msgstr "Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ–Ñнує" msgid "can not move directory into itself" msgstr "неможливо переміÑтити директорію в Ñаму Ñебе" -msgid "cannot move directory over file" -msgstr "неможливо переміÑтити директорію поверх файлу" +msgid "destination already exists" +msgstr "Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð¶Ðµ Ñ–Ñнує" msgid "source directory is empty" msgstr "Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ñ–Ñ Ð´Ð¶ÐµÑ€ÐµÐ»Ð° порожнÑ" @@ -8789,7 +8833,6 @@ msgstr "не вдалоÑÑ Ñкопіювати нотатки з \"%s\" в \"% #. TRANSLATORS: the first %s will be replaced by a git #. notes command: 'add', 'merge', 'remove', etc. #. - #, c-format msgid "refusing to %s notes in %s (outside of refs/notes/)" msgstr "відмовлено в %s нотаток у %s (за межами refs/notes/)" @@ -9096,6 +9139,10 @@ msgid "inconsistency with delta count" msgstr "неÑÐ¿Ñ–Ð²Ð¿Ð°Ð´Ñ–Ð½Ð½Ñ Ð· підрахунком дельти" #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "неприпуÑтиме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ pack.allowPackReuse: \"%s\"" + +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -9333,9 +9380,6 @@ msgstr "мінімальний розмір пакунка - 1 МіБ" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin не можна викориÑтовувати Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ–Ð½Ð´ÐµÐºÑованого пакунка" -msgid "cannot use --filter without --stdout" -msgstr "неможливо викориÑтовувати --filter без --stdout" - msgid "cannot use --filter with --stdin-packs" msgstr "неможливо викориÑтовувати --filter з --stdin-packs" @@ -9348,19 +9392,16 @@ msgstr "неможливо викориÑтовувати внутрішній Ñ msgid "cannot use --stdin-packs with --cruft" msgstr "неможливо викориÑтовувати --stdin-packs з --cruft" -msgid "cannot use --max-pack-size with --cruft" -msgstr "неможливо викориÑтовувати --max-pack-size з --cruft" - msgid "Enumerating objects" msgstr "ÐŸÐµÑ€ÐµÑ€Ð°Ñ…ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ñ–Ð²" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "Ð’Ñього %<PRIu32> (дельта %<PRIu32>), повторно викориÑтано %<PRIu32> (дельта " -"%<PRIu32>), повторно викориÑтано пакунків %<PRIu32>" +"%<PRIu32>), повторно викориÑтано пакунків %<PRIu32> (з %<PRIuMAX>)" msgid "" "'git pack-redundant' is nominated for removal.\n" @@ -10349,16 +10390,6 @@ msgstr "" msgid "switch `C' expects a numerical value" msgstr "перемикач \"C\" очікує чиÑлове значеннÑ" -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy потребує --merge або --interactive" - -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "" -"apply опції неÑуміÑні з rebase.autoSquash. РозглÑньте можливіÑть Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ " -"--no-autosquash" - msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -10879,7 +10910,6 @@ msgstr "(без URL-адреÑи)" #. with the one in " Fetch URL: %s" #. translation. #. - #, c-format msgid " Push URL: %s" msgstr " URL-адреÑа надÑиланнÑ: %s" @@ -11071,6 +11101,10 @@ msgstr "не вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ тимчаÑовий файл зніРmsgid "could not remove stale bitmap: %s" msgstr "не вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ заÑтарілий bitmap: %s" +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð¿Ð°ÐºÑƒÐ½ÐºÑƒ %s не починаєтьÑÑ Ð· objdir %s" + msgid "pack everything in a single pack" msgstr "запакувати вÑе в один пакунок" @@ -11145,19 +11179,22 @@ msgid "write a multi-pack index of the resulting packs" msgstr "запиÑати multi-pack-index результуючих пакунків" msgid "pack prefix to store a pack containing pruned objects" -msgstr "Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð¿Ð°ÐºÑƒÐ½ÐºÐ° Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿Ð°ÐºÑƒÐ½ÐºÐ° з обрізаними обʼєктами" +msgstr "Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿Ð°ÐºÑƒÐ½ÐºÐ° з обрізаними обʼєктами" + +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿Ð°ÐºÑƒÐ½ÐºÐ° з відфільтрованими обʼєктами" msgid "cannot delete packs in a precious-objects repo" msgstr "неможливо видалити пакунки в precious-objects Ñховищі" +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "Ð¾Ð¿Ñ†Ñ–Ñ \"%s\" може бути викориÑтана тільки разом з \"%s\"" + msgid "Nothing new to pack." msgstr "Ðемає нічого нового Ð´Ð»Ñ Ð¿Ð°ÐºÑƒÐ²Ð°Ð½Ð½Ñ." #, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð¿Ð°ÐºÑƒÐ½ÐºÑƒ %s не починаєтьÑÑ Ð· objdir %s" - -#, c-format msgid "renaming pack to '%s' failed" msgstr "Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð°ÐºÑƒÐ½ÐºÐ° на \"%s\" завершилоÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾" @@ -11357,6 +11394,75 @@ msgstr "--convert-graft-file не потребує аргументів" msgid "only one pattern can be given with -l" msgstr "тільки один шаблон може бути заданий з -l" +msgid "need some commits to replay" +msgstr "потрібні деÑкі комміти Ð´Ð»Ñ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ" + +msgid "--onto and --advance are incompatible" +msgstr "--onto та --advance неÑуміÑні" + +msgid "all positive revisions given must be references" +msgstr "вÑÑ– надані позитивні ревізії мають бути поÑиланнÑми" + +msgid "argument to --advance must be a reference" +msgstr "аргумент до --advance має бути поÑиланнÑм" + +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "" +"неможливо проÑунути поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð· декількома джерелами, тому що впорÑÐ´ÐºÑƒÐ²Ð°Ð½Ð½Ñ " +"буде нечітко визначеним" + +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "неможливо неÑвно визначити, чи це Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ --advance або --onto" + +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "" +"неможливо проÑунути поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð· декількома джерельними гілками, тому що " +"впорÑÐ´ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ нечітко визначеним" + +msgid "cannot implicitly determine correct base for --onto" +msgstr "неможливо неÑвно визначити вірну базу Ð´Ð»Ñ --onto" + +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(ЕКСПЕРИМЕÐТÐЛЬÐО!) git replay ([--contained] --onto <нова-база> | --advance " +"<гілка>) <діапазон-ревізій>..." + +msgid "make replay advance given branch" +msgstr "зробити Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð· проÑуваннÑм даної гілки" + +msgid "replay onto given commit" +msgstr "відтворити на заданий коміт" + +msgid "advance all branches contained in revision-range" +msgstr "проÑунути вÑÑ– гілки, що міÑÑ‚ÑтьÑÑ Ð² діапазоні ревізій" + +msgid "option --onto or --advance is mandatory" +msgstr "Ð¾Ð¿Ñ†Ñ–Ñ --onto або --advance Ñ” обовʼÑзковою" + +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "" +"деÑкі опції Ð¿Ñ€Ð¾Ñ…Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾ ревізіÑм будуть перевизначені, оÑкільки біт " +"\"%s\" у \"struct rev_info\" буде примуÑово викориÑтано" + +msgid "error preparing revisions" +msgstr "помилка при підготовці ревізій" + +msgid "replaying down to root commit is not supported yet!" +msgstr "Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð¾ кореневого коміту поки що не підтримуєтьÑÑ!" + +msgid "replaying merge commits is not supported yet!" +msgstr "Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ð¼Ñ–Ñ‚Ñ–Ð² Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð¿Ð¾ÐºÐ¸ що не підтримуєтьÑÑ!" + msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" msgstr "" @@ -11569,18 +11675,12 @@ msgstr "--prefix потребує аргументу" msgid "unknown mode for --abbrev-ref: %s" msgstr "невідомий режим Ð´Ð»Ñ --abbrev-ref: %s" -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden не можна викориÑтовувати разом з --branches" - -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden неможливо викориÑтовувати разом з --tags" - -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden неможливо викориÑтовувати разом з --remotes" - msgid "this operation must be run in a work tree" msgstr "цю операцію треба виконувати в робочому дереві" +msgid "Could not read the index" +msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ індекÑ" + #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "невідомий режим Ð´Ð»Ñ --show-object-format: %s" @@ -11932,24 +12032,44 @@ msgid "Unknown hash algorithm" msgstr "Ðевідомий хеш-алгоритм" msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-d | --" -"dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<н>]] [--abbrev[=<н>]] [--tags]\n" " [--heads] [--] [<шаблон>...]" +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<н>]] [--abbrev[=<н>]]\n" +" [--] [<поÑиланнÑ>...]" + msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<шаблон>]" +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <поÑиланнÑ>" + +msgid "reference does not exist" +msgstr "поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ðµ Ñ–Ñнує" + +msgid "failed to look up reference" +msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ поÑиланнÑ" + msgid "only show tags (can be combined with heads)" msgstr "показати тільки теги (можна комбінувати з верхівками)" msgid "only show heads (can be combined with tags)" msgstr "показати тільки верхівки (можна комбінувати з тегами)" +msgid "check for reference existence without resolving" +msgstr "перевірÑти наÑвніÑть поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð±ÐµÐ· розвʼÑзаннÑ" + msgid "stricter reference checking, requires exact ref path" msgstr "більш Ñувора перевірка поÑилань, потребує точного шлÑху до поÑиланнÑ" @@ -12778,6 +12898,9 @@ msgstr "" "[no-]recommend-shallow] [--reference <Ñховище>] [--recursive] [--[no-]single-" "branch] [--] [<шлÑÑ…>...]" +msgid "Failed to resolve HEAD as a valid ref." +msgstr "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ð²Ê¼Ñзати HEAD в дійÑне поÑиланнÑ." + msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<опції>] [<шлÑÑ…>...]" @@ -13248,8 +13371,11 @@ msgstr "(Ð´Ð»Ñ Ð²Ð¸Ñокорівневих команд) забути збер msgid "write index in this format" msgstr "запиÑати Ñ–Ð½Ð´ÐµÐºÑ Ñƒ цьому форматі" +msgid "report on-disk index format version" +msgstr "звітувати про верÑÑ–ÑŽ формату індекÑу на диÑку" + msgid "enable or disable split index" -msgstr "увімкнути або вимкнути розщеплений індекÑ" +msgstr "увімкнути або вимкнути розділений індекÑ" msgid "enable/disable untracked cache" msgstr "увімкнути/вимкнути невідÑтежуваний кеш" @@ -13272,19 +13398,27 @@ msgstr "позначити файли придатними Ð´Ð»Ñ fsmonitor" msgid "clear fsmonitor valid bit" msgstr "очиÑтити біт придатноÑті Ð´Ð»Ñ fsmonitor" +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "верÑÑ–Ñ Ñ–Ð½Ð´ÐµÐºÑу: була %d, Ñтала %d" + msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" msgstr "" "core.splitIndex вÑтановлено в false; видаліть або змініть його, Ñкщо ви " -"дійÑно хочете увімкнути розщеплений індекÑ" +"дійÑно хочете увімкнути розділений індекÑ" msgid "" "core.splitIndex is set to true; remove or change it, if you really want to " "disable split index" msgstr "" "core.splitIndex вÑтановлено в true; видаліть або змініть його, Ñкщо ви " -"дійÑно хочете вимкнути розщеплений індекÑ" +"дійÑно хочете вимкнути розділений індекÑ" msgid "" "core.untrackedCache is set to true; remove or change it, if you really want " @@ -13427,13 +13561,13 @@ msgstr "Ðемає можливої джерельної гілки, що озн #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan -b %s %s\n" msgstr "" -"Якщо ви хочете Ñтворити робоче дерево, що міÑтить нову ÑирітÑьку гілку\n" +"Якщо ви хочете Ñтворити робоче дерево, що міÑтить нову ненароджену гілку\n" "(гілку без комітів) Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñховища, ви можете зробити це\n" "за допомогою Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñ --orphan:\n" "\n" @@ -13441,13 +13575,13 @@ msgstr "" #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan %s\n" msgstr "" -"Якщо ви хочете Ñтворити робоче дерево, що міÑтить нову ÑирітÑьку гілку\n" +"Якщо ви хочете Ñтворити робоче дерево, що міÑтить нову ненароджену гілку\n" "(гілку без комітів) Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñховища, ви можете зробити це\n" "за допомогою Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñ --orphan:\n" "\n" @@ -13511,6 +13645,10 @@ msgid "initializing" msgstr "ініціалізаціÑ" #, c-format +msgid "could not find created worktree '%s'" +msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñтворене робоче дерево \"%s\"" + +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "Підготовка робочого дерева (нова гілка \"%s\")" @@ -13542,16 +13680,12 @@ msgstr "" msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" "Ðе Ñ–Ñнує локальних або віддалених поÑилань, незважаючи на наÑвніÑть " "принаймні одного віддаленого\n" -"призначеннÑ, зупинка; ÑкориÑтайтеÑÑŒ \"add -f\", щоб перевизначити або " -"Ñпочатку отримати віддалене поÑиланнÑ" - -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "\"%s\" Ñ– \"%s\" не можна викориÑтовувати разом" +"призначеннÑ, зупинка; ÑкориÑтайтеÑÑŒ \"add -f\", щоб перевизначити, або " +"Ñпочатку виконайте Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð· віддаленного Ñховища" msgid "checkout <branch> even if already checked out in other worktree" msgstr "" @@ -13563,8 +13697,8 @@ msgstr "Ñтворити нову гілку" msgid "create or reset a branch" msgstr "Ñтворити або Ñкинути гілку" -msgid "create unborn/orphaned branch" -msgstr "Ñтворити ненароджену/ÑирітÑьку гілку" +msgid "create unborn branch" +msgstr "Ñтворити ненароджену гілку" msgid "populate the new working tree" msgstr "заповнити нове робоче дерево" @@ -13587,11 +13721,8 @@ msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "опції \"%s\", \"%s\" та \"%s\" не можна викориÑтовувати разом" #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "опції \"%s\" Ñ– \"%s\" не можна викориÑтовувати разом" - -msgid "<commit-ish>" -msgstr "<комітоподібне>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "опцію \"%s\" не можна викориÑтовувати разом з комітоподібними" msgid "added with --lock" msgstr "додано з --lock" @@ -13870,6 +14001,10 @@ msgid "terminating chunk id appears earlier than expected" msgstr "ідентифікатор Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ„Ñ€Ð°Ð³Ð¼ÐµÐ½Ñ‚Ð° зʼÑвивÑÑ Ñ€Ð°Ð½Ñ–ÑˆÐµ, ніж очікувалоÑÑŒ" #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "шматок id %<PRIx32> не Ñ” %d-byte впорÑдкованим" + +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "невірне Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ ÑˆÐ¼Ð°Ñ‚ÐºÐ°(ів) %<PRIx64> та %<PRIx64>" @@ -13921,8 +14056,8 @@ msgstr "Зібрати інформацію, щоб кориÑтувач міг msgid "Move objects and refs by archive" msgstr "ПеренеÑти архів обʼєктів та поÑилань" -msgid "Provide content or type and size information for repository objects" -msgstr "Показати вміÑÑ‚ або інформацію про тип Ñ– розмір обʼєктів Ñховища" +msgid "Provide contents or details of repository objects" +msgstr "Ðадавати вміÑÑ‚ або деталі обʼєктів Ñховища" msgid "Display gitattributes information" msgstr "Відобразити інформацію про gitattributes" @@ -14210,6 +14345,11 @@ msgstr "Запакувати розпаковані обʼєкти у Ñхови msgid "Create, list, delete refs to replace objects" msgstr "Створити, показати, видалити поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ñ–Ð² заміни" +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "" +"ЕКСПЕРИМЕÐТÐЛЬÐО: Ð’Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ð¼Ñ–Ñ‚Ñ–Ð² на новій базі також працює з " +"порожніми Ñховищами" + msgid "Generates a summary of pending changes" msgstr "Створює підÑумок змін Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð»Ñду" @@ -14331,8 +14471,8 @@ msgstr "Перевірити GPG-Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ñ‚ÐµÐ³Ñ–Ð²" msgid "Display version information about Git" msgstr "Показати інформацію про верÑÑ–ÑŽ Git" -msgid "Show logs with difference each commit introduces" -msgstr "Показати журнал з різницею, Ñку вноÑить кожен коміт" +msgid "Show logs with differences each commit introduces" +msgstr "Показати журнал з різницÑми, Ñкі вноÑить кожен коміт" msgid "Manage multiple working trees" msgstr "Керувати кількома робочими деревами" @@ -14448,6 +14588,32 @@ msgstr "ІнÑтрумент Ð´Ð»Ñ ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÐ»Ð¸ÐºÐ¸Ð¼Ð¸ Ñхов msgid "commit-graph file is too small" msgstr "файл коміт-графа занадто малий" +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "шматок oid fanout коміт-графа має невірний розмір" + +msgid "commit-graph fanout values out of order" +msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ fanout коміт-графа впорÑдковані невірно" + +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "шматок OID lookup коміт-графа має невірний розмір" + +msgid "commit-graph commit data chunk is wrong size" +msgstr "шматок commit data коміт-графа має невірний розмір" + +msgid "commit-graph generations chunk is wrong size" +msgstr "шматок generations коміт-графа має невірний розмір" + +msgid "commit-graph changed-path index chunk is too small" +msgstr "шматок changed-path index коміт-графа має невірний розмір" + +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "" +"Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð½Ð°Ð´Ñ‚Ð¾ малого шматка changed-path (%<PRIuMAX> < %<PRIuMAX>) " +"файла коміт-графа" + #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "Ð¿Ñ–Ð´Ð¿Ð¸Ñ ÐºÐ¾Ð¼Ñ–Ñ‚-графа %X не збігаєтьÑÑ Ð· підпиÑом %X" @@ -14464,9 +14630,21 @@ msgstr "хеш верÑÑ–Ñ ÐºÐ¾Ð¼Ñ–Ñ‚-графа %X не збігаєтьÑÑ Ð msgid "commit-graph file is too small to hold %u chunks" msgstr "файл коміт-графа занадто малий, щоб вміÑтити %u шматків" +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "необхідний шматок OID fanout коміт-графа відÑутній або пошкоджений" + +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "необхідний шматок OID lookup коміт-графа відÑутній або пошкоджений" + +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "необхідний шматок commit data коміт-графа відÑутній або пошкоджений" + msgid "commit-graph has no base graphs chunk" msgstr "коміт-граф не має шматка базових графів" +msgid "commit-graph base graphs chunk is too small" +msgstr "шматок base graphs коміт-графа занадто малий" + msgid "commit-graph chain does not match" msgstr "ланцюжок коміт-графа не Ñпівпадає" @@ -14474,6 +14652,9 @@ msgstr "ланцюжок коміт-графа не Ñпівпадає" msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "кількіÑть комітів у базовому графі занадто велика: %<PRIuMAX>" +msgid "commit-graph chain file too small" +msgstr "файл ланцюжка коміт-графа занадто малий" + #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" msgstr "неприпуÑтимий ланцюжок коміт-графа: Ñ€Ñдок \"%s\" не Ñ” хешем" @@ -14489,7 +14670,13 @@ msgid "could not find commit %s" msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ коміт %s" msgid "commit-graph requires overflow generation data but has none" -msgstr "коміт-граф потребує даних генерації переповненнÑ, але Ñ—Ñ… немаєданих" +msgstr "коміт-граф потребує даних генерації переповненнÑ, але не має Ñ—Ñ…" + +msgid "commit-graph overflow generation data is too small" +msgstr "занадто мало даних генерації Ð¿ÐµÑ€ÐµÐ¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚-графа" + +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "extra-edges pointer коміт-графа виходить за межі" msgid "Loading known commits in commit graph" msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ð¾Ð¼Ð¸Ñ… комітів у коміт-графі" @@ -14615,18 +14802,6 @@ msgid "commit-graph parent list for commit %s terminates early" msgstr "ÑпиÑок батьків коміт-графа Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ %s завершивÑÑ Ð¿ÐµÑ€ÐµÐ´Ñ‡Ð°Ñно" #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" -"коміт-граф має нульовий номер генерації Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ %s, але ненульовий деінде" - -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" -"коміт-граф має ненульовий номер генерації Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ %s, але нульовий деінде" - -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ ÐºÐ¾Ð¼Ñ–Ñ‚-графа Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ %s Ñ” %<PRIuMAX> < %<PRIuMAX>" @@ -14634,6 +14809,14 @@ msgstr "Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ ÐºÐ¾Ð¼Ñ–Ñ‚-графа Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ %s Ñ” %<PRI msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>" msgstr "дата коміту Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ %s у коміт-графі Ñ” %<PRIuMAX> != %<PRIuMAX>" +#, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "" +"коміт-граф має Ñк нульові, так Ñ– ненульові генерації (наприклад, коміти " +"\"%s\" Ñ– \"%s\")" + msgid "Verifying commits in commit graph" msgstr "Перевірка комітів у коміт-графі" @@ -14661,6 +14844,10 @@ msgstr "" "\"git config advice.graftFileDeprecated false\"" #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "коміт %s Ñ–Ñнує в коміт-графі, але не в базі даних обʼєктів" + +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "Коміт %s має недоÑтовірний GPG-підпиÑ, нібито від %s." @@ -15101,10 +15288,6 @@ msgstr "поÑÐ¸Ð»Ð°Ð½Ð½Ñ \"%s\" не вказує на blob" msgid "unable to resolve config blob '%s'" msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ñ‚Ð¸ config blob \"%s\"" -#, c-format -msgid "failed to parse %s" -msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ %s" - msgid "unable to parse command-line config" msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ конфігурацію командного Ñ€Ñдка" @@ -15268,7 +15451,6 @@ msgid "unable to look up %s (port %s) (%s)" msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ %s (порт %s) (%s)" #. TRANSLATORS: this is the end of "Looking up %s ... " - #, c-format msgid "" "done.\n" @@ -15286,7 +15468,6 @@ msgstr "" "%s" #. TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " - msgid "done." msgstr "готово." @@ -15522,7 +15703,6 @@ msgstr[1] "%<PRIuMAX> роки" msgstr[2] "%<PRIuMAX> років" #. TRANSLATORS: "%s" is "<n> years" - #, c-format msgid "%s, %<PRIuMAX> month ago" msgid_plural "%s, %<PRIuMAX> months ago" @@ -15585,9 +15765,6 @@ msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати архів" msgid "--merge-base does not work with ranges" msgstr "--merge-base не працює з діапазонами" -msgid "--merge-base only works with commits" -msgstr "--merge-base працює лише з комітами" - msgid "unable to get HEAD" msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ HEAD" @@ -15649,6 +15826,10 @@ msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "Ðевідоме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ð¹Ð½Ð¾Ñ— змінної \"diff.submodule\": \"%s\"" #, c-format +msgid "unknown value for config '%s': %s" +msgstr "невідоме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ— \"%s\": %s" + +#, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" @@ -15728,13 +15909,6 @@ msgstr "невірний --color-moved аргумент: %s" msgid "invalid mode '%s' in --color-moved-ws" msgstr "неприпуÑтимий режим \"%s\" у --color-moved-ws" -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"Ð¾Ð¿Ñ†Ñ–Ñ diff-algorithm приймає Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \"myers\", \"minimal\", \"patience\" " -"та \"histogram\"" - #, c-format msgid "invalid argument to %s" msgstr "неприпуÑтимий аргумент до %s" @@ -15778,8 +15952,8 @@ msgstr "машинний вивід --stat" msgid "output only the last line of --stat" msgstr "вивеÑти лише оÑтанній Ñ€Ñдок --stat" -msgid "<param1,param2>..." -msgstr "<параметр1,параметр2>..." +msgid "<param1>,<param2>..." +msgstr "<параметр1>,<параметр2>..." msgid "" "output the distribution of relative amount of changes for each sub-directory" @@ -15788,8 +15962,8 @@ msgstr "вивеÑти розподіл відноÑної кількоÑті з msgid "synonym for --dirstat=cumulative" msgstr "Ñинонім Ð´Ð»Ñ --dirstat=cumulative" -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "Ñинонім Ð´Ð»Ñ --dirstat=files,параметр1,параметр2..." +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "Ñинонім Ð´Ð»Ñ --dirstat=files,<параметр1>,<параметр2>..." msgid "warn if changes introduce conflict markers or whitespace errors" msgstr "" @@ -15965,12 +16139,6 @@ msgstr "згенерувати різницю за алгоритмом \"patien msgid "generate diff using the \"histogram diff\" algorithm" msgstr "згенерувати різницю за алгоритмом \"histogram diff\"" -msgid "<algorithm>" -msgstr "<алгоритм>" - -msgid "choose a diff algorithm" -msgstr "вибрати алгоритм різниці" - msgid "<text>" msgstr "<текÑÑ‚>" @@ -16351,7 +16519,6 @@ msgstr "помилка при обробці підтверджень: %d" #. TRANSLATORS: The parameter will be 'ready', a protocol #. keyword. #. - #, c-format msgid "expected packfile to be sent after '%s'" msgstr "очікувалоÑÑŒ надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° пакунка піÑÐ»Ñ \"%s\"" @@ -16359,7 +16526,6 @@ msgstr "очікувалоÑÑŒ надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð° пакунка п #. TRANSLATORS: The parameter will be 'ready', a protocol #. keyword. #. - #, c-format msgid "expected no other sections to be sent after no '%s'" msgstr "не очікувалоÑÑŒ надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¶Ð¾Ð´Ð½Ð¾Ñ— Ñекції Ð´Ð»Ñ ÑтатуÑу не \"%s\"" @@ -17014,12 +17180,12 @@ msgstr "" "Ðе вдалоÑÑ Ð·Ð»Ð¸Ñ‚Ð¸ підмодуль %s, але Ñ–Ñнує кілька можливих варіантів злиттÑ:\n" "%s" -msgid "Failed to execute internal merge" -msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ внутрішнє злиттÑ" +msgid "failed to execute internal merge" +msgstr "не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ внутрішнє злиттÑ" #, c-format -msgid "Unable to add %s to database" -msgstr "Ðе вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ %s до бази даних" +msgid "unable to add %s to database" +msgstr "не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ %s до бази даних" #, c-format msgid "Auto-merging %s" @@ -17172,9 +17338,8 @@ msgstr "" #. conflict in a submodule. The first argument is the submodule #. name, and the second argument is the abbreviated id of the #. commit that needs to be merged. For example: -#. - go to submodule (mysubmodule), and either merge commit abc1234" +#. - go to submodule (mysubmodule), and either merge commit abc1234" #. - #, c-format msgid "" " - go to submodule (%s), and either merge commit %s\n" @@ -17210,7 +17375,6 @@ 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. #. - #, c-format msgid "collecting merge info failed for trees %s, %s, %s" msgstr "Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— про Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð½Ðµ вдалоÑÑ Ð´Ð»Ñ Ð´ÐµÑ€ÐµÐ² %s, %s, %s" @@ -17461,7 +17625,20 @@ msgid "failed to read the cache" msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ кеш" msgid "multi-pack-index OID fanout is of the wrong size" -msgstr "multi-pack-index OID fanout має невірний розмір" +msgstr "multi-pack-index OID розÑÑ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð¼Ð°Ñ” невірний розмір" + +#, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"невірна поÑлідовніÑть oid fanout: fanout[%d] = %<PRIx32> > %<PRIx32> = " +"fanout[%d]" + +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "multi-pack-index OID lookup шматок має невірний розмір" + +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "multi-pack-index object offset шматок має невірний розмір" #, c-format msgid "multi-pack-index file %s is too small" @@ -17479,17 +17656,23 @@ msgstr "multi-pack-index верÑÑ–Ñ %d не розпізнана" msgid "multi-pack-index hash version %u does not match version %u" msgstr "верÑÑ–Ñ Ñ…ÐµÑˆÑƒ multi-pack-index %u не збігаєтьÑÑ Ð· верÑією %u" -msgid "multi-pack-index missing required pack-name chunk" -msgstr "multi-pack-index недоÑтає необхідного фрагмента імені пакунка" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "необхідний шматок pack-name multi-pack-index відÑутній або пошкоджений" -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "multi-pack-index недоÑтає необхідного OID fanout фрагмента" +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "" +"необхідний шматок OID fanout multi-pack-index відÑутній або пошкоджений" -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "multi-pack-index недоÑтає необхідного OID lookup фрагмента" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "" +"необхідний шматок OID lookup multi-pack-index відÑутній або пошкоджений" + +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "" +"необхідний шматок object offsets multi-pack-index відÑутній або пошкоджений" -msgid "multi-pack-index missing required object offsets chunk" -msgstr "multi-pack-index недоÑтає необхідного фрагмента Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ñ–Ð²" +msgid "multi-pack-index pack-name chunk is too short" +msgstr "шматок pack-name multi-pack-index занадто малий" #, c-format msgid "multi-pack-index pack names out of order: '%s' before '%s'" @@ -17501,10 +17684,20 @@ msgstr "" msgid "bad pack-int-id: %u (%u total packs)" msgstr "невірний pack-int-id: %u (%u вÑього пакунків)" +msgid "MIDX does not contain the BTMP chunk" +msgstr "MIDX не міÑтить шматок BTMP" + +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ бітмаповий пакунок %<PRIu32>" + msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "" "multi-pack-index зберігає 64-бітне зміщеннÑ, але Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ off_t занадто мале" +msgid "multi-pack-index large offset out of bounds" +msgstr "large offset multi-pack-index виходить за межі" + #, c-format msgid "failed to add packfile '%s'" msgstr "не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ packfile \"%s\"" @@ -17583,13 +17776,6 @@ msgstr "невірна контрольна Ñума" msgid "Looking for referenced packfiles" msgstr "Пошук файлів пакунків, на Ñкі Ñ” поÑиланнÑ" -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "" -"невірна поÑлідовноÑть oid fanout: fanout[%d] = %<PRIx32> > %<PRIx32> = " -"fanout[%d]" - msgid "the midx contains no oid" msgstr "midx не міÑтить oid" @@ -17672,7 +17858,6 @@ msgstr "Відмовлено в перезапиÑÑ– нотаток у %s (за #. the environment variable, the second %s is #. its value. #. - #, c-format msgid "Bad %s value: '%s'" msgstr "Ðевірне %s значеннÑ: \"%s\"" @@ -17887,7 +18072,6 @@ msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ð¿Ð°ÐºÑƒÐ²Ð°Ñ‚Ð¸ вміÑÑ‚ %s" #. output shown when we cannot look up or parse the #. object in question. E.g. "deadbeef [bad object]". #. - #, c-format msgid "%s [bad object]" msgstr "%s [невірний обʼект]" @@ -17895,9 +18079,8 @@ msgstr "%s [невірний обʼект]" #. TRANSLATORS: This is a line of ambiguous commit #. object output. E.g.: #. * -#. "deadbeef commit 2021-01-01 - Some Commit Message" +#. "deadbeef commit 2021-01-01 - Some Commit Message" #. - #, c-format msgid "%s commit %s - %s" msgstr "%s коміт %s - %s" @@ -17905,7 +18088,7 @@ msgstr "%s коміт %s - %s" #. TRANSLATORS: This is a line of ambiguous #. tag object output. E.g.: #. * -#. "deadbeef tag 2022-01-01 - Some Tag Message" +#. "deadbeef tag 2022-01-01 - Some Tag Message" #. * #. The second argument is the YYYY-MM-DD found #. in the tag. @@ -17913,7 +18096,6 @@ msgstr "%s коміт %s - %s" #. The third argument is the "tag" string #. from object.c. #. - #, c-format msgid "%s tag %s - %s" msgstr "%s тег %s - %s" @@ -17922,9 +18104,8 @@ msgstr "%s тег %s - %s" #. tag object output where we couldn't parse #. the tag itself. E.g.: #. * -#. "deadbeef [bad tag, could not parse it]" +#. "deadbeef [bad tag, could not parse it]" #. - #, c-format msgid "%s [bad tag, could not parse it]" msgstr "%s [невірний тег, не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸]" @@ -17932,7 +18113,6 @@ msgstr "%s [невірний тег, не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸]" #. TRANSLATORS: This is a line of ambiguous <type> #. object output. E.g. "deadbeef tree". #. - #, c-format msgid "%s tree" msgstr "%s дерево" @@ -17940,7 +18120,6 @@ msgstr "%s дерево" #. TRANSLATORS: This is a line of ambiguous <type> #. object output. E.g. "deadbeef blob". #. - #, c-format msgid "%s blob" msgstr "%s blob" @@ -17953,7 +18132,6 @@ msgstr "короткий ідентифікатор обʼєкта %s неодн #. objects composed in show_ambiguous_object(). See #. its "TRANSLATORS" comments for details. #. - #, c-format msgid "" "The candidates are:\n" @@ -18122,6 +18300,9 @@ msgstr "у мультіпакунковому bitmap відÑутній необ msgid "could not open pack %s" msgstr "не вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ пакунок %s" +msgid "could not determine MIDX preferred pack" +msgstr "не вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ бажаний пакунок MIDX" + #, c-format msgid "preferred pack (%s) is invalid" msgstr "бажаний пакунок (%s) Ñ” неприпуÑтимим" @@ -18143,6 +18324,12 @@ msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\"" msgstr "пошкоджений ewah bitmap: урізаний заголовок Ð´Ð»Ñ bitmap коміту \"%s\"" #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "" +"не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ пакунок: \"%s\", Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾Ð³Ð¾ викориÑÑ‚Ð°Ð½Ð½Ñ " +"пакунків" + +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "обʼєкт \"%s\" не знайдено в типах bitmap" @@ -18233,6 +18420,12 @@ msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "" "невірна Ð¿Ð¾Ð·Ð¸Ñ†Ñ–Ñ Ð·Ð²Ð¾Ñ€Ð¾Ñ€Ñ‚Ð½Ð¾Ð³Ð¾ індекÑу у %<PRIu64>: %<PRIu32> != %<PRIu32>" +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "multi-pack-index reverse-index шматок має невірний розмір" + +msgid "could not determine preferred pack" +msgstr "не вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ бажаний пакунок" + msgid "cannot both write and verify reverse index" msgstr "неможливо одночаÑно запиÑувати та звірÑти зворотний індекÑ" @@ -18284,14 +18477,6 @@ msgid "%s requires a value" msgstr "%s потребує значеннÑ" #, c-format -msgid "%s is incompatible with %s" -msgstr "%s неÑуміÑний з %s" - -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s : неÑуміÑний з чимоÑÑŒ іншим" - -#, c-format msgid "%s takes no value" msgstr "%s не приймає значеннÑ" @@ -18340,7 +18525,6 @@ msgstr "викориÑтаннÑ: %s" #. TRANSLATORS: the colon here should align with the #. one in "usage: %s" translation. #. - #, c-format msgid " or: %s" msgstr " або: %s" @@ -18364,7 +18548,6 @@ msgstr " або: %s" #. translated) N_() usage string, which contained embedded #. newlines before we split it up. #. - #, c-format msgid "%*s%s" msgstr "%*s%s" @@ -18376,6 +18559,10 @@ msgstr " %s" msgid "-NUM" msgstr "-NUM" +#, c-format +msgid "opposite of --no-%s" +msgstr "протилежне --no-%s" + msgid "expiry-date" msgstr "Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñтроку дії" @@ -18407,6 +18594,14 @@ msgstr "" "Ñимволом NUL" #, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "невірне булеве Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¾Ñ‚Ð¾Ñ‡ÐµÐ½Ð½Ñ \"%s\" Ð´Ð»Ñ \"%s\"" + +#, c-format +msgid "failed to parse %s" +msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ %s" + +#, c-format msgid "Could not make %s writable by group" msgstr "Ðе вдалоÑÑ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ %s доÑтупним Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу групою" @@ -18457,6 +18652,10 @@ msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s: \"literal\" та \"glob\" неÑуміÑні" #, c-format +msgid "'%s' is outside the directory tree" +msgstr "\"%s\" знаходитьÑÑ Ð¿Ð¾Ð·Ð° деревом директорій" + +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s: \"%s\" знаходитьÑÑ Ð·Ð° межами Ñховища за адреÑою \"%s\"" @@ -18611,10 +18810,6 @@ msgid "unable to add '%s' to index" msgstr "не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ \"%s\" до індекÑу" #, c-format -msgid "unable to stat '%s'" -msgstr "не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ stat Ð´Ð»Ñ \"%s\"" - -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "\"%s\" відображаєтьÑÑ Ñк файл Ñ– Ñк каталог" @@ -18716,16 +18911,12 @@ msgid "broken index, expect %s in %s, got %s" msgstr "пошкоджений індекÑ, очікувавÑÑ %s у %s, отримано %s" msgid "cannot write split index for a sparse index" -msgstr "неможливо запиÑати розщеплений Ñ–Ð½Ð´ÐµÐºÑ Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ñ–Ð´Ð¶ÐµÐ½Ð¾Ð³Ð¾ індекÑу" +msgstr "неможливо запиÑати розділений Ñ–Ð½Ð´ÐµÐºÑ Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ñ–Ð´Ð¶ÐµÐ½Ð¾Ð³Ð¾ індекÑу" msgid "failed to convert to a sparse-index" msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ в sparse-index" #, c-format -msgid "could not stat '%s'" -msgstr "не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ stat '%s'" - -#, c-format msgid "unable to open git dir: %s" msgstr "не вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ git-директорію: %s" @@ -18964,7 +19155,7 @@ msgstr "очікувалоÑÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s=" #, c-format msgid "positive value expected '%s' in %%(%s)" -msgstr "очікувалоÑÑŒ додатне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \"%s\" у %%(%s)" +msgstr "очікувалоÑÑŒ додатне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ \"%s\" в %%(%s)" #, c-format msgid "expected format: %%(align:<width>,<position>)" @@ -19192,10 +19383,6 @@ msgid "cannot process '%s' and '%s' at the same time" msgstr "неможливо обробити \"%s\" Ñ– \"%s\" одночаÑно" #, c-format -msgid "could not remove reference %s" -msgstr "не вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ поÑÐ¸Ð»Ð°Ð½Ð½Ñ %s" - -#, c-format msgid "could not delete reference %s: %s" msgstr "не вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ поÑÐ¸Ð»Ð°Ð½Ð½Ñ %s: %s" @@ -19376,7 +19563,6 @@ msgstr "визначник поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð¶ÐµÑ€ÐµÐ»Ð° %s збігаєть #. <remote> <src>:<dst>" push, and "being pushed ('%s')" is #. the <src>. #. - #, c-format msgid "" "The destination you provided is not a full refname (i.e.,\n" @@ -19682,7 +19868,7 @@ msgstr "--unpacked=<файл пакунка> більше не Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼ÑƒÑ #, c-format msgid "invalid option '%s' in --stdin mode" -msgstr "неприпуÑтима Ð¾Ð¿Ñ†Ñ–Ñ \"%s\" у режимі --stdin" +msgstr "неприпуÑтима Ð¾Ð¿Ñ†Ñ–Ñ \"%s\" у --stdin режимі" msgid "your current branch appears to be broken" msgstr "ваша поточна гілка виглÑдає пошкодженою" @@ -19771,8 +19957,15 @@ msgid "only download metadata for the branch that will be checked out" msgstr "" "завантажити метадані тільки Ð´Ð»Ñ Ð³Ñ–Ð»ÐºÐ¸, на Ñку буде здійÑнюватиÑÑ Ð¿ÐµÑ€ÐµÑ…Ñ–Ð´" -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "ÑкалÑрний клон [<опції>] [--] <Ñховище> [<директоріÑ>]" +msgid "create repository within 'src' directory" +msgstr "Ñтворити Ñховище в директорії \"src\"" + +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <головна-гілка>] [--full-clone]\n" +"\t[--[no-]src] <URL-адреÑа> [<коренева-директоріÑ>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -19823,12 +20016,28 @@ msgid "could not remove stale scalar.repo '%s'" msgstr "неможливо видалити заÑтаріле scalar.repo \"%s\"" #, c-format -msgid "removing stale scalar.repo '%s'" -msgstr "Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ñтарілого scalar.repo \"%s\"" +msgid "removed stale scalar.repo '%s'" +msgstr "видалено заÑтаріле scalar.repo \"%s\"" #, c-format -msgid "git repository gone in '%s'" -msgstr "git Ñховище зникло у \"%s\"" +msgid "repository at '%s' has different owner" +msgstr "у Ñховища \"%s\" інший влаÑник" + +#, c-format +msgid "repository at '%s' has a format issue" +msgstr "невірній формат Ñховища \"%s\"" + +#, c-format +msgid "repository not found in '%s'" +msgstr "Ñховище \"%s\" не знайдено" + +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"щоб ÑкаÑувати реєÑтрацію цього репозиторію в Scalar, виконайте\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" msgid "" "scalar run <task> [<enlistment>]\n" @@ -20000,7 +20209,6 @@ msgstr "зробіть коміт або додайте ваші зміни до #. TRANSLATORS: %s will be "revert", "cherry-pick" or #. "rebase". #. - #, c-format msgid "%s: Unable to write new index file" msgstr "%s: Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати новий індекÑний файл" @@ -20234,16 +20442,11 @@ msgstr "неможливо отримати Ð´Ð¾Ð¿Ð¸Ñ Ð´Ð¾ коміту Ð´Ð»Ñ #. TRANSLATORS: The first %s will be a "todo" command like #. "revert" or "pick", the second %s a SHA1. - #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ джерельний коміт %s" #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ \"%s\" на \"%s\"" - -#, c-format msgid "could not revert %s... %s" msgstr "не вдалоÑÑ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ Ð²Ð¸Ð²ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ %s... %s" @@ -20566,6 +20769,9 @@ msgstr "ЗаÑтоÑÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ñхову призвело до кон msgid "Autostash exists; creating a new stash entry." msgstr "ÐвтоÑхов Ñ–Ñнує; ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ запиÑу Ñхову." +msgid "autostash reference is a symref" +msgstr "поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ñхову Ñ” Ñимвольним поÑиланнÑм" + msgid "could not detach HEAD" msgstr "не вдалоÑÑ Ð²Ñ–Ð´Ê¼Ñ”Ð´Ð½Ð°Ñ‚Ð¸ HEAD" @@ -20599,14 +20805,14 @@ msgstr "" " git rebase --continue\n" #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "ÐŸÐµÑ€ÐµÐ±Ð°Ð·ÑƒÐ²Ð°Ð½Ð½Ñ (%d/%d)%s" - -#, c-format msgid "Stopped at %s... %.*s\n" msgstr "Зупинено на %s... %.*s\n" #, c-format +msgid "Rebasing (%d/%d)%s" +msgstr "ÐŸÐµÑ€ÐµÐ±Ð°Ð·ÑƒÐ²Ð°Ð½Ð½Ñ (%d/%d)%s" + +#, c-format msgid "unknown command %d" msgstr "невідома команда %d" @@ -20887,6 +21093,10 @@ msgid "invalid initial branch name: '%s'" msgstr "неприпуÑтиме початкове Ñ–Ð¼â€™Ñ Ð³Ñ–Ð»ÐºÐ¸: \"%s\"" #, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "re-init: ігноровано --initial-branch=%s" + +#, c-format msgid "unable to handle file type %d" msgstr "не вдалоÑÑ Ð¾Ð±Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ тип файлу %d" @@ -20897,15 +21107,15 @@ msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити %s на %s" msgid "attempt to reinitialize repository with different hash" msgstr "Ñпроба переініціалізувати репозиторій з іншим хеш-алгоритмом" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "Ñпроба переініціалізувати Ñховище з іншим форматом зберіганнÑ" + #, c-format msgid "%s already exists" msgstr "%s вже Ñ–Ñнує" #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "re-init: ігноровано --initial-branch=%s" - -#, c-format msgid "Reinitialized existing shared Git repository in %s%s\n" msgstr "Переініціалізовано Ñ–Ñнуюче Ñпільне Git Ñховище в %s%s\n" @@ -20923,35 +21133,42 @@ msgstr "Ініціалізовано порожнє Git Ñховище в %s%s\n #, c-format msgid "index entry is a directory, but not sparse (%08x)" -msgstr "індекÑний Ð·Ð°Ð¿Ð¸Ñ Ñ” директорією, але не Ñ” розрідженим (%08x)" +msgstr "Ð·Ð°Ð¿Ð¸Ñ Ñ–Ð½Ð´ÐµÐºÑу Ñ” директорією, але не розрідженою (%08x)" msgid "cannot use split index with a sparse index" -msgstr "не можна викориÑтовувати розщеплений Ñ–Ð½Ð´ÐµÐºÑ Ð· розрідженим індекÑом" +msgstr "неможливо викориÑтовувати розділений Ñ–Ð½Ð´ÐµÐºÑ Ð· розрідженим індекÑом" +#. TRANSLATORS: IEC 80000-13:2008 gibibyte #, c-format msgid "%u.%2.2u GiB" msgstr "%u.%2.2u ГіБ" +#. TRANSLATORS: IEC 80000-13:2008 gibibyte/second #, c-format msgid "%u.%2.2u GiB/s" msgstr "%u.%2.2u ГіБ/Ñ" +#. TRANSLATORS: IEC 80000-13:2008 mebibyte #, c-format msgid "%u.%2.2u MiB" msgstr "%u.%2.2u МіБ" +#. TRANSLATORS: IEC 80000-13:2008 mebibyte/second #, c-format msgid "%u.%2.2u MiB/s" msgstr "%u.%2.2u МіБ/Ñ" +#. TRANSLATORS: IEC 80000-13:2008 kibibyte #, c-format msgid "%u.%2.2u KiB" msgstr "%u.%2.2u КіБ" +#. TRANSLATORS: IEC 80000-13:2008 kibibyte/second #, c-format msgid "%u.%2.2u KiB/s" msgstr "%u.%2.2u КіБ/Ñ" +#. TRANSLATORS: IEC 80000-13:2008 byte #, c-format msgid "%u byte" msgid_plural "%u bytes" @@ -20959,6 +21176,7 @@ msgstr[0] "%u байт" msgstr[1] "%u байти" msgstr[2] "%u байтів" +#. TRANSLATORS: IEC 80000-13:2008 byte/second #, c-format msgid "%u byte/s" msgid_plural "%u bytes/s" @@ -21168,12 +21386,6 @@ msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "" "кількіÑть запиÑів у дереві кешу, Ñкі потрібно анулювати (за замовчуваннÑм 0)" -msgid "unhandled options" -msgstr "необроблені опції" - -msgid "error preparing revisions" -msgstr "помилка при підготовці ревізій" - #, c-format msgid "commit %s is not marked reachable" msgstr "коміт %s не позначений Ñк доÑÑжний" @@ -21330,9 +21542,6 @@ msgstr "вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑˆÐ»Ñху до віддаленого Ñерв msgid "invalid remote service path" msgstr "неприпуÑтимий шлÑÑ… до віддаленої Ñлужби" -msgid "operation not supported by protocol" -msgstr "Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ð¾Ð¼" - #, c-format msgid "can't connect to subservice %s" msgstr "неможливо підключитиÑÑ Ð´Ð¾ підÑервіÑу %s" @@ -21465,10 +21674,6 @@ msgid "support for protocol v2 not implemented yet" msgstr "підтримка протоколу v2 ще не запроваджена" #, c-format -msgid "unknown value for config '%s': %s" -msgstr "невідоме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ— \"%s\": %s" - -#, c-format msgid "transport '%s' not allowed" msgstr "заÑіб передачі \"%s\" не дозволений" @@ -21520,6 +21725,9 @@ msgstr "bundle-uri Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ Ð¿Ñ€Ð¾Ñ‚Ð¾Ðº msgid "could not retrieve server-advertised bundle-uri list" msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ ÑпиÑок Ð°Ð´Ñ€ÐµÑ Ð¿Ð°ÐºÐµÑ‚Ñ–Ð², оголошений Ñервером" +msgid "operation not supported by protocol" +msgstr "Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ð¾Ð¼" + msgid "too-short tree object" msgstr "занадто короткий обʼєкт дерева" @@ -21917,8 +22125,11 @@ msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ доÑтуп до \"%s\"" msgid "unable to get current working directory" msgstr "не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ поточну робочу директорію" +msgid "unable to get random bytes" +msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ випадкові байти" + msgid "Unmerged paths:" -msgstr "не злиті шлÑхи:" +msgstr "Ðе злиті шлÑхи:" msgid " (use \"git restore --staged <file>...\" to unstage)" msgstr "" @@ -22059,7 +22270,7 @@ msgstr "" "Ви можете викориÑтати параметр '--no-ahead-behind', щоб уникнути цього.\n" msgid "You have unmerged paths." -msgstr "У Ð²Ð°Ñ Ñ” не злиті шлÑхи." +msgstr "У Ð²Ð°Ñ Ñ” незлиті шлÑхи." msgid " (fix conflicts and run \"git commit\")" msgstr " (виправте конфлікти та виконайте \"git commit\")" @@ -22359,7 +22570,6 @@ msgid "ahead " msgstr "попереду " #. TRANSLATORS: the action is e.g. "pull with rebase" - #, c-format msgid "cannot %s: You have unstaged changes." msgstr "неможливо %s: У Ð²Ð°Ñ Ñ” неіндекÑовані зміни." @@ -22371,6 +22581,10 @@ msgstr "крім того, ваш Ñ–Ð½Ð´ÐµÐºÑ Ð¼Ñ–Ñтить незакоміч msgid "cannot %s: Your index contains uncommitted changes." msgstr "неможливо виконати %s: Ваш Ñ–Ð½Ð´ÐµÐºÑ Ð¼Ñ–Ñтить незакомічені зміни." +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "невідомий Ñтиль \"%s\" наданий Ð´Ð»Ñ \"%s\"" + msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" @@ -22555,18 +22769,17 @@ msgstr "" "ОчиÑтіть вміÑÑ‚ тіла, Ñкщо ви не бажаєте надÑилати підÑумок.\n" #, perl-format -msgid "Failed to open %s: %s" -msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ %s: %s" - -#, perl-format msgid "Failed to open %s.final: %s" msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ %s.final: %s" +#, perl-format +msgid "Failed to open %s: %s" +msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ %s: %s" + msgid "Summary email is empty, skipping it\n" msgstr "ПідÑумковий лиÑÑ‚ порожній, пропущено\n" #. TRANSLATORS: please keep [y/N] as is. - #, perl-format msgid "Are you sure you want to use <%s> [y/N]? " msgstr "Ви впевнені, що хочете викориÑтати <%s> [y/N]? " @@ -22611,7 +22824,6 @@ msgstr "помилка: не вдалоÑÑ Ð²Ð¸Ñ‚Ñгти дійÑну адре #. TRANSLATORS: Make sure to include [q] [d] [e] in your #. translation. The program will only accept English input #. at this point. - msgid "What to do with this address? ([q]uit|[d]rop|[e]dit): " msgstr "Що робити з цією адреÑою? ([q]uit|[d]rop|[e]dit): " @@ -22646,7 +22858,6 @@ msgstr "" #. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your #. translation. The program will only accept English input #. at this point. - msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): " msgstr "ÐадіÑлати цей лиÑÑ‚? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): " @@ -22762,7 +22973,6 @@ msgid "Skipping %s with backup suffix '%s'.\n" msgstr "ПропуÑк %s з ÑуфікÑом резервної копії \"%s\".\n" #. TRANSLATORS: please keep "[y|N]" as is. - #, perl-format msgid "Do you really want to send %s? [y|N]: " msgstr "Ви дійÑно хочете відправити %s? [y|N]: " diff --git a/po/zh_CN.po b/po/zh_CN.po index b70ae3866b..39efaf1012 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -46,6 +46,7 @@ # commit | æäº¤ # commit message | æäº¤è¯´æ˜Ž # commit object | æäº¤å¯¹è±¡ +# commit-graph | æäº¤å›¾ # commit-ish (also committish) | æäº¤å· # cone | é”¥å½¢ï¼ˆç¨€ç–æ£€å‡ºæ¨¡åž‹ï¼‰ï¼›é”¥ï¼ˆç¨€ç–检出) # conflict | å†²çª @@ -99,6 +100,7 @@ # plumbing | 管件(Git åº•å±‚æ ¸å¿ƒå‘½ä»¤çš„åˆ«ç§°ï¼‰ # porcelain | 瓷件(Git 上层å°è£…命令的别称) # precious-objects repo | çå“仓库 +# preferred pack | 首选包(多包索引ä¸å¼•入的首选包概念) # promisor | 承诺者 # prune | 清除 # pull | æ‹‰ï¼Œæ‹‰å– @@ -151,8 +153,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-18 10:21+0800\n" -"PO-Revision-Date: 2023-08-18 19:29+0800\n" +"POT-Creation-Date: 2024-02-16 14:27+0800\n" +"PO-Revision-Date: 2024-02-18 11:47+0800\n" "Last-Translator: Teng Long <dyroneteng@gmail.com>\n" "Language-Team: GitHub <https://github.com/dyrone/git/>\n" "Language: zh_CN\n" @@ -1031,7 +1033,7 @@ msgid "unclosed quote" msgstr "未关é—的引å·" #: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c -#: builtin/receive-pack.c builtin/tag.c +#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c msgid "too many arguments" msgstr "å¤ªå¤šå‚æ•°" @@ -1045,14 +1047,16 @@ msgstr "未能识别的空白å—符选项 '%s'" msgid "unrecognized whitespace ignore option '%s'" msgstr "未能识别的空白å—符忽略选项 '%s'" -#: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout.c -#: builtin/clone.c builtin/commit.c builtin/describe.c builtin/diff-tree.c -#: builtin/difftool.c builtin/fast-export.c builtin/fetch.c builtin/help.c -#: builtin/index-pack.c builtin/init-db.c builtin/log.c builtin/ls-files.c -#: builtin/merge-base.c builtin/merge.c builtin/pack-objects.c builtin/push.c -#: builtin/rebase.c builtin/repack.c builtin/reset.c builtin/rev-list.c -#: builtin/show-branch.c builtin/stash.c builtin/submodule--helper.c -#: builtin/tag.c builtin/worktree.c parse-options.c range-diff.c revision.c +#: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c +#: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c +#: builtin/describe.c builtin/diff-tree.c builtin/difftool.c +#: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c +#: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c +#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c +#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-list.c +#: builtin/rev-parse.c builtin/show-branch.c builtin/stash.c +#: builtin/submodule--helper.c builtin/tag.c builtin/worktree.c parse-options.c +#: range-diff.c revision.c #, c-format msgid "options '%s' and '%s' cannot be used together" msgstr "选项 '%s' å’Œ '%s' ä¸èƒ½åŒæ—¶ä½¿ç”¨" @@ -1529,7 +1533,7 @@ msgid_plural "%d lines applied after fixing whitespace errors." msgstr[0] "ä¿®å¤ç©ºç™½é”™è¯¯åŽï¼Œåº”用了 %d 行。" msgstr[1] "ä¿®å¤ç©ºç™½é”™è¯¯åŽï¼Œåº”用了 %d 行。" -#: apply.c builtin/add.c builtin/mv.c builtin/rm.c +#: apply.c builtin/mv.c builtin/rm.c msgid "Unable to write new index file" msgstr "æ— æ³•å†™å…¥æ–°ç´¢å¼•æ–‡ä»¶" @@ -1860,6 +1864,11 @@ msgstr "æœªçŸ¥å‚æ•° --output" #: archive.c #, c-format +msgid "extra command line parameter '%s'" +msgstr "é¢å¤–çš„å‘½ä»¤è¡Œå‚æ•°ï¼š'%s'" + +#: archive.c +#, c-format msgid "Unknown archive format '%s'" msgstr "æœªçŸ¥å½’æ¡£æ ¼å¼ '%s'" @@ -1914,6 +1923,17 @@ msgstr "忽略过大的 gitattributes æ•°æ®å¯¹è±¡ '%s'" msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "错误的 --attr-source 或 GIT_ATTR_SOURCE" +#: attr.c read-cache.c +#, c-format +msgid "unable to stat '%s'" +msgstr "æ— æ³•å¯¹ %s 执行 stat" + +#: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c +#: builtin/pack-objects.c combine-diff.c rerere.c +#, c-format +msgid "unable to read %s" +msgstr "ä¸èƒ½è¯» %s" + #: bisect.c #, c-format msgid "Badly quoted content in file '%s': %s" @@ -2234,8 +2254,8 @@ msgstr "忍¡ç»„ '%s':ä¸èƒ½åˆ›å»ºåˆ†æ”¯ '%s'" #: branch.c #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "'%s' å·²ç»æ£€å‡ºåˆ° '%s'" +msgid "'%s' is already used by worktree at '%s'" +msgstr "'%s' å·²ç»è¢«å·¥ä½œåŒº '%s' 使用" #: builtin/add.c msgid "git add [<options>] [--] <pathspec>..." @@ -2258,30 +2278,26 @@ msgstr "" "设置 add.interactive.useBuiltin å·²ç»è¢«ç§»é™¤ï¼\n" "查看 'git help config' ä¸çš„相关æ¡ç›®ä»¥èŽ·å–æ›´å¤šä¿¡æ¯ã€‚" -#: builtin/add.c builtin/rev-parse.c -msgid "Could not read the index" -msgstr "ä¸èƒ½è¯»å–索引" - #: builtin/add.c -msgid "Could not write patch" -msgstr "ä¸èƒ½ç”Ÿæˆè¡¥ä¸" +msgid "could not read the index" +msgstr "ä¸èƒ½è¯»å–索引" #: builtin/add.c msgid "editing patch failed" msgstr "编辑补ä¸å¤±è´¥" -#: builtin/add.c +#: builtin/add.c read-cache.c #, c-format -msgid "Could not stat '%s'" +msgid "could not stat '%s'" msgstr "ä¸èƒ½å¯¹ '%s' 调用 stat" #: builtin/add.c -msgid "Empty patch. Aborted." -msgstr "空补ä¸ã€‚异常终æ¢ã€‚" +msgid "empty patch. aborted" +msgstr "空补ä¸ã€‚异常终æ¢" #: builtin/add.c #, c-format -msgid "Could not apply '%s'" +msgid "could not apply '%s'" msgstr "ä¸èƒ½åº”用 '%s'" #: builtin/add.c @@ -2440,14 +2456,19 @@ msgstr "" msgid "index file corrupt" msgstr "索引文件æŸå" +#: builtin/add.c builtin/am.c builtin/checkout.c builtin/clone.c +#: builtin/commit.c builtin/stash.c merge.c rerere.c +msgid "unable to write new index file" +msgstr "æ— æ³•å†™æ–°çš„ç´¢å¼•æ–‡ä»¶" + #: builtin/am.c builtin/mailinfo.c mailinfo.c #, c-format msgid "bad action '%s' for '%s'" msgstr "'%2$s' 的错误动作 '%1$s'" #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c -#: builtin/pull.c diff-merges.c gpg-interface.c ls-refs.c parallel-checkout.c -#: sequencer.c setup.c +#: builtin/pull.c config.c diff-merges.c gpg-interface.c ls-refs.c +#: parallel-checkout.c sequencer.c setup.c #, c-format msgid "invalid value for '%s': '%s'" msgstr "'%s' çš„å€¼æ— æ•ˆï¼š'%s'" @@ -2600,8 +2621,7 @@ msgstr "git write-tree æ— æ³•å†™å…¥æ ‘å¯¹è±¡" msgid "applying to an empty history" msgstr "æ£åº”用到一个空历å²ä¸Š" -#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c -#: t/helper/test-fast-rebase.c +#: builtin/am.c builtin/commit.c builtin/merge.c builtin/replay.c sequencer.c msgid "failed to write commit object" msgstr "æ— æ³•å†™æäº¤å¯¹è±¡" @@ -2689,11 +2709,6 @@ msgstr "" "您应该对已ç»å†²çªè§£å†³çš„æ¯ä¸€ä¸ªæ–‡ä»¶æ‰§è¡Œ 'git add' æ¥æ ‡è®°å·²ç»å®Œæˆã€‚ \n" "您å¯ä»¥å¯¹ \"ç”±ä»–ä»¬åˆ é™¤\" 的文件执行 `git rm` 命令。" -#: builtin/am.c builtin/checkout.c builtin/clone.c builtin/stash.c merge.c -#: rerere.c -msgid "unable to write new index file" -msgstr "æ— æ³•å†™æ–°çš„ç´¢å¼•æ–‡ä»¶" - #: builtin/am.c builtin/reset.c #, c-format msgid "Could not parse object '%s'." @@ -2715,11 +2730,6 @@ msgid "failed to read '%s'" msgstr "æ— æ³•è¯»å– '%s'" #: builtin/am.c -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "选项 '%s=%s' å’Œ '%s=%s' ä¸èƒ½åŒæ—¶ä½¿ç”¨" - -#: builtin/am.c msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<选项>] [(<mbox> | <Maildir>)...]" @@ -2791,8 +2801,9 @@ msgid "n" msgstr "n" #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c -#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c -#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c +#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c +#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c +#: builtin/verify-tag.c msgid "format" msgstr "æ ¼å¼" @@ -2922,10 +2933,10 @@ msgstr "git archive:应有一个 flush 包" #: builtin/bisect.c msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=<术è¯> --term-{old,good}=<术è¯>] [--no-" +"git bisect start [--term-{new|bad}=<术è¯> --term-{old|good}=<术è¯>] [--no-" "checkout] [--first-parent] [<å> [<好>...]] [--] [<è·¯å¾„è§„æ ¼>...]" #: builtin/bisect.c @@ -2945,8 +2956,8 @@ msgid "git bisect replay <logfile>" msgstr "git bisect replay <日志文件>" #: builtin/bisect.c -msgid "git bisect run <cmd>..." -msgstr "git bisect run <命令>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <命令> [<傿•°>...]" #: builtin/bisect.c #, c-format @@ -3461,37 +3472,38 @@ msgstr "git branch [<选项>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" "å°†è¦åˆ 除的分支 '%s' å·²ç»è¢«åˆå¹¶åˆ°\n" -" '%s',但未åˆå¹¶åˆ° HEAD。" +" '%s',但未åˆå¹¶åˆ° HEAD" # è¯‘è€…ï¼šä¿æŒåŽŸæ¢è¡Œæ ¼å¼ï¼Œåœ¨è¾“出时 %s 的替代内容会让å—符串å˜é•¿ #: builtin/branch.c #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" -"å¹¶æœªåˆ é™¤åˆ†æ”¯ '%s', 虽然它已ç»åˆå¹¶åˆ° HEAD,\n" -" 然而å´å°šæœªè¢«åˆå¹¶åˆ°åˆ†æ”¯ '%s' 。" +"å¹¶æœªåˆ é™¤åˆ†æ”¯ '%s',虽然它已ç»åˆå¹¶åˆ° HEAD,\n" +" 然而å´å°šæœªè¢«åˆå¹¶åˆ°åˆ†æ”¯ '%s'" #: builtin/branch.c #, c-format -msgid "Couldn't look up commit object for '%s'" +msgid "couldn't look up commit object for '%s'" msgstr "æ— æ³•æŸ¥è¯¢ '%s' 指å‘çš„æäº¤å¯¹è±¡" #: builtin/branch.c #, 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 "" -"分支 '%s' 没有完全åˆå¹¶ã€‚\n" -"如果您确认è¦åˆ 除它,执行 'git branch -D %s'。" +msgid "the branch '%s' is not fully merged" +msgstr "分支 '%s' 没有完全åˆå¹¶" #: builtin/branch.c -msgid "Update of config-file failed" +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" +msgstr "如果您确认è¦åˆ 除它,执行 'git branch -D %s'" + +#: builtin/branch.c +msgid "update of config-file failed" msgstr "æ›´æ–°é…置文件失败" #: builtin/branch.c @@ -3500,13 +3512,13 @@ msgstr "ä¸èƒ½å°† -a å’Œ -d åŒæ—¶ä½¿ç”¨" #: builtin/branch.c #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "æ— æ³•åˆ é™¤æ£€å‡ºäºŽ '%2$s' 的分支 '%1$s'。" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "æ— æ³•å¼ºåˆ¶æ›´æ–°è¢«å·¥ä½œåŒº '%2$s' 所使用的分支 '%1$s'" #: builtin/branch.c #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "未能找到远程跟踪分支 '%s'。" +msgid "remote-tracking branch '%s' not found" +msgstr "未能找到远程跟踪分支 '%s'" #: builtin/branch.c #, c-format @@ -3519,8 +3531,8 @@ msgstr "" #: builtin/branch.c #, c-format -msgid "branch '%s' not found." -msgstr "分支 '%s' 未å‘现。" +msgid "branch '%s' not found" +msgstr "分支 '%s' 未å‘现" #: builtin/branch.c #, c-format @@ -3547,12 +3559,12 @@ msgstr "HEAD (%s) æŒ‡å‘ refs/heads/ 之外" #: builtin/branch.c #, c-format -msgid "Branch %s is being rebased at %s" +msgid "branch %s is being rebased at %s" msgstr "分支 %s æ£è¢«å˜åŸºåˆ° %s" #: builtin/branch.c #, c-format -msgid "Branch %s is being bisected at %s" +msgid "branch %s is being bisected at %s" msgstr "分支 %s æ£è¢«äºŒåˆ†æŸ¥æ‰¾äºŽ %s" #: builtin/branch.c @@ -3562,48 +3574,48 @@ msgstr "工作区 %s çš„ HEAD æŒ‡å‘æ²¡æœ‰è¢«æ›´æ–°" #: builtin/branch.c #, c-format -msgid "Invalid branch name: '%s'" +msgid "invalid branch name: '%s'" msgstr "æ— æ•ˆçš„åˆ†æ”¯å:'%s'" #: builtin/branch.c #, c-format -msgid "No commit on branch '%s' yet." -msgstr "分支 '%s' å°šæ— æäº¤ã€‚" +msgid "no commit on branch '%s' yet" +msgstr "分支 '%s' å°šæ— æäº¤" #: builtin/branch.c #, c-format -msgid "No branch named '%s'." -msgstr "没有分支 '%s'。" +msgid "no branch named '%s'" +msgstr "没有分支 '%s'" #: builtin/branch.c -msgid "Branch rename failed" +msgid "branch rename failed" msgstr "分支é‡å‘½å失败" #: builtin/branch.c -msgid "Branch copy failed" +msgid "branch copy failed" msgstr "分支拷è´å¤±è´¥" #: builtin/branch.c #, c-format -msgid "Created a copy of a misnamed branch '%s'" +msgid "created a copy of a misnamed branch '%s'" msgstr "已为错误命å的分支 '%s' 创建了一个副本" #: builtin/branch.c #, c-format -msgid "Renamed a misnamed branch '%s' away" +msgid "renamed a misnamed branch '%s' away" msgstr "已将错误命å的分支 '%s' é‡å‘½å" #: builtin/branch.c #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "分支é‡å‘½å为 %s,但 HEAD 没有更新ï¼" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "分支é‡å‘½å为 %s,但 HEAD 没有更新" #: builtin/branch.c -msgid "Branch is renamed, but update of config-file failed" +msgid "branch is renamed, but update of config-file failed" msgstr "分支被é‡å‘½å,但更新é…置文件失败" #: builtin/branch.c -msgid "Branch is copied, but update of config-file failed" +msgid "branch is copied, but update of config-file failed" msgstr "分支已拷è´ï¼Œä½†æ›´æ–°é…置文件失败" #: builtin/branch.c @@ -3754,9 +3766,9 @@ msgstr "åœ¨åæ¨¡ç»„ä¸é€’å½’" msgid "format to use for the output" msgstr "è¾“å‡ºæ ¼å¼" -#: builtin/branch.c builtin/submodule--helper.c submodule.c -msgid "Failed to resolve HEAD as a valid ref." -msgstr "æ— æ³•å°† HEAD è§£æžä¸ºæœ‰æ•ˆå¼•用。" +#: builtin/branch.c +msgid "failed to resolve HEAD as a valid ref" +msgstr "æ— æ³•å°† HEAD è§£æžä¸ºæœ‰æ•ˆå¼•用" #: builtin/branch.c builtin/clone.c msgid "HEAD not found below refs/heads!" @@ -3778,7 +3790,7 @@ msgid "branch name required" msgstr "å¿…é¡»æä¾›åˆ†æ”¯å" #: builtin/branch.c -msgid "Cannot give description to detached HEAD" +msgid "cannot give description to detached HEAD" msgstr "ä¸èƒ½å‘分离头指针æä¾›æè¿°" #: builtin/branch.c @@ -3786,12 +3798,12 @@ msgid "cannot edit description of more than one branch" msgstr "ä¸èƒ½ä¸ºä¸€ä¸ªä»¥ä¸Šçš„分支编辑æè¿°" #: builtin/branch.c -msgid "cannot copy the current branch while not on any." -msgstr "ä¸å¤„äºŽä»»ä½•åˆ†æ”¯ä¸Šï¼Œæ— æ³•æ‹·è´å½“å‰åˆ†æ”¯ã€‚" +msgid "cannot copy the current branch while not on any" +msgstr "ä¸å¤„äºŽä»»ä½•åˆ†æ”¯ä¸Šï¼Œæ— æ³•æ‹·è´å½“å‰åˆ†æ”¯" #: builtin/branch.c -msgid "cannot rename the current branch while not on any." -msgstr "ä¸å¤„äºŽä»»ä½•åˆ†æ”¯ä¸Šï¼Œæ— æ³•é‡å‘½å当å‰åˆ†æ”¯ã€‚" +msgid "cannot rename the current branch while not on any" +msgstr "ä¸å¤„äºŽä»»ä½•åˆ†æ”¯ä¸Šï¼Œæ— æ³•é‡å‘½å当å‰åˆ†æ”¯" #: builtin/branch.c msgid "too many branches for a copy operation" @@ -3808,8 +3820,8 @@ msgstr "为设置新上游æä¾›äº†å¤ªå¤šçš„傿•°" #: builtin/branch.c #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." -msgstr "æ— æ³•è®¾ç½® HEAD 的上游为 %sï¼Œå› ä¸º HEAD 没有指å‘任何分支。" +"could not set upstream of HEAD to %s when it does not point to any branch" +msgstr "æ— æ³•è®¾ç½® HEAD 的上游为 %sï¼Œå› ä¸º HEAD 没有指å‘任何分支" #: builtin/branch.c #, c-format @@ -3826,17 +3838,17 @@ msgid "too many arguments to unset upstream" msgstr "ä¸ºå–æ¶ˆä¸Šæ¸¸è®¾ç½®æ“作æä¾›äº†å¤ªå¤šçš„傿•°" #: builtin/branch.c -msgid "could not unset upstream of HEAD when it does not point to any branch." +msgid "could not unset upstream of HEAD when it does not point to any branch" msgstr "æ— æ³•å–æ¶ˆ HEAD çš„ä¸Šæ¸¸è®¾ç½®å› ä¸ºå®ƒæ²¡æœ‰æŒ‡å‘一个分支" #: builtin/branch.c #, c-format -msgid "Branch '%s' has no upstream information" +msgid "branch '%s' has no upstream information" msgstr "分支 '%s' 没有上游信æ¯" #: builtin/branch.c msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"the -a, and -r, options to 'git branch' do not take a branch name.\n" "Did you mean to use: -a|-r --list <pattern>?" msgstr "" "'git branch' çš„ -a å’Œ -r 选项ä¸å¸¦ä¸€ä¸ªåˆ†æ”¯å。\n" @@ -3845,9 +3857,8 @@ msgstr "" #: builtin/branch.c msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." -msgstr "" -"ä¸å†æ”¯æŒé€‰é¡¹ '--set-upstream'。请使用 '--track' 或 '--set-upstream-to'。" +"'--set-upstream-to' instead" +msgstr "ä¸å†æ”¯æŒé€‰é¡¹ '--set-upstream'。请使用 '--track' 或 '--set-upstream-to'" #: builtin/bugreport.c msgid "git version:\n" @@ -3930,6 +3941,11 @@ msgstr "æŒ‡å®šé”™è¯¯æŠ¥å‘Šæ–‡ä»¶çš„ç›®æ ‡ä½ç½®" msgid "specify a strftime format suffix for the filename(s)" msgstr "指定文件的 strftime æ ¼å¼åŽç¼€" +#: builtin/bugreport.c +#, c-format +msgid "unknown argument `%s'" +msgstr "æœªçŸ¥å‚æ•° `%s'" + #: builtin/bugreport.c builtin/diagnose.c #, c-format msgid "could not create leading directories for '%s'" @@ -4069,6 +4085,14 @@ msgstr "git cat-file (-t | -s) [--allow-unknown-type] <对象>" #: builtin/cat-file.c msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<版本>:<路径|æ ‘å¯¹è±¡> | --path=<路径|æ ‘å¯¹è±¡> <版本>]" + +#: builtin/cat-file.c +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -4080,14 +4104,6 @@ msgstr "" " [--textconv | --filters] [-Z]" #: builtin/cat-file.c -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<版本>:<路径|æ ‘å¯¹è±¡> | --path=<路径|æ ‘å¯¹è±¡> <版本>]" - -#: builtin/cat-file.c msgid "Check object existence or emit object contents" msgstr "检查对象å˜åœ¨æˆ–输出对象内容" @@ -4464,6 +4480,11 @@ msgstr "'%s' 或 '%s' ä¸èƒ½å’Œ %s 一起使用" #: builtin/checkout.c #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "'%s'ã€'%s' 或 '%s' ä¸èƒ½åœ¨æ£€å‡ºä¸€ä¸ªæ ‘时使用" + +#: builtin/checkout.c +#, c-format msgid "path '%s' is unmerged" msgstr "路径 '%s' 未åˆå¹¶" @@ -4489,7 +4510,7 @@ msgstr "ä¸èƒ½å¯¹ '%s' 执行 reflog æ“作:%s\n" msgid "HEAD is now at" msgstr "HEAD ç›®å‰ä½äºŽ" -#: builtin/checkout.c builtin/clone.c t/helper/test-fast-rebase.c +#: builtin/checkout.c builtin/clone.c msgid "unable to update HEAD" msgstr "ä¸èƒ½æ›´æ–° HEAD" @@ -4758,8 +4779,8 @@ msgid "new-branch" msgstr "新分支" #: builtin/checkout.c -msgid "new unparented branch" -msgstr "新的没有父æäº¤çš„分支" +msgid "new unborn branch" +msgstr "新的未诞生的分支" #: builtin/checkout.c builtin/merge.c msgid "update ignored files (default)" @@ -4825,7 +4846,7 @@ msgstr "" msgid "you must specify path(s) to restore" msgstr "æ‚¨å¿…é¡»æŒ‡å®šè¦æ¢å¤çš„路径" -#: builtin/checkout.c builtin/clone.c builtin/remote.c +#: builtin/checkout.c builtin/clone.c builtin/remote.c builtin/replay.c #: builtin/submodule--helper.c builtin/worktree.c msgid "branch" msgstr "分支" @@ -5066,10 +5087,6 @@ msgid "" msgstr "" "clean.requireForce 默认为 true 且未æä¾› -iã€-n 或 -f é€‰é¡¹ï¼Œæ‹’ç»æ‰§è¡Œæ¸…ç†åŠ¨ä½œ" -#: builtin/clean.c -msgid "-x and -X cannot be used together" -msgstr "-x å’Œ -X ä¸èƒ½åŒæ—¶ä½¿ç”¨" - #: builtin/clone.c msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<选项>] [--] <仓库> [<路径>]" @@ -5148,7 +5165,7 @@ msgstr "检出 <分支> è€Œä¸æ˜¯è¿œç¨‹ HEAD" msgid "path to git-upload-pack on the remote" msgstr "远程 git-upload-pack 路径" -#: builtin/clone.c builtin/fetch.c builtin/grep.c builtin/pull.c +#: builtin/clone.c builtin/fetch.c builtin/pull.c msgid "depth" msgstr "深度" @@ -5161,6 +5178,7 @@ msgid "create a shallow clone since a specific time" msgstr "从一个特定时间创建一个浅克隆" #: builtin/clone.c builtin/fetch.c builtin/pull.c builtin/rebase.c +#: builtin/replay.c msgid "revision" msgstr "版本" @@ -5188,6 +5206,10 @@ msgstr "git目录" msgid "separate git dir from working tree" msgstr "git目录和工作区分离" +#: builtin/clone.c builtin/init-db.c +msgid "specify the reference format to use" +msgstr "指定è¦ä½¿ç”¨çš„å¼•ç”¨æ ¼å¼" + #: builtin/clone.c msgid "key=value" msgstr "key=value" @@ -5337,11 +5359,10 @@ msgstr "å¤ªå¤šå‚æ•°ã€‚" msgid "You must specify a repository to clone." msgstr "您必须指定一个仓库æ¥å…‹éš†ã€‚" -#: builtin/clone.c -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "--bundle-uri 与 --depthã€--shallow-since å’Œ --shallow-exclude ä¸å…¼å®¹" +#: builtin/clone.c builtin/init-db.c setup.c +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "未知的引用å˜å‚¨æ ¼å¼ '%s'" #: builtin/clone.c #, c-format @@ -5502,7 +5523,7 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <目录>] [--append]\n" " [--split[=<ç–ç•¥>]] [--reachable | --stdin-packs | --" @@ -5521,12 +5542,17 @@ msgstr "ä¿å˜å›¾å½¢çš„对象目录" #: builtin/commit-graph.c msgid "if the commit-graph is split, only verify the tip file" -msgstr "如果æäº¤å›¾å½¢è¢«æ‹†åˆ†ï¼ŒåªéªŒè¯å¤´ä¸€ä¸ªæ–‡ä»¶" +msgstr "如果æäº¤å›¾è¢«æ‹†åˆ†ï¼ŒåªéªŒè¯å¤´ä¸€ä¸ªæ–‡ä»¶" #: builtin/commit-graph.c #, c-format msgid "Could not open commit-graph '%s'" -msgstr "æ— æ³•æ‰“å¼€æäº¤å›¾å½¢ '%s'" +msgstr "æ— æ³•æ‰“å¼€æäº¤å›¾ '%s'" + +#: builtin/commit-graph.c +#, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "æ— æ³•æ‰“å¼€æäº¤å›¾é“¾ '%s'" #: builtin/commit-graph.c #, c-format @@ -5570,15 +5596,15 @@ msgstr "å¯ç”¨å˜æ›´è·¯å¾„的计算" #: builtin/commit-graph.c msgid "allow writing an incremental commit-graph file" -msgstr "å…è®¸å†™ä¸€ä¸ªå¢žé‡æäº¤å›¾å½¢æ–‡ä»¶" +msgstr "å…è®¸å†™ä¸€ä¸ªå¢žé‡æäº¤å›¾æ–‡ä»¶" #: builtin/commit-graph.c msgid "maximum number of commits in a non-base split commit-graph" -msgstr "在éžåŸºæœ¬æ‹†åˆ†æäº¤å›¾å½¢ä¸çš„æœ€å¤§æäº¤æ•°" +msgstr "在éžåŸºæœ¬æ‹†åˆ†æäº¤å›¾ä¸çš„æœ€å¤§æäº¤æ•°" #: builtin/commit-graph.c msgid "maximum ratio between two levels of a split commit-graph" -msgstr "一个拆分æäº¤å›¾å½¢çš„两个级别之间的最大比率" +msgstr "一个拆分æäº¤å›¾çš„两个级别之间的最大比率" #: builtin/commit-graph.c msgid "only expire files older than a given date-time" @@ -5769,10 +5795,6 @@ msgid "Failed to update main cache tree" msgstr "ä¸èƒ½æ›´æ–°æ ‘的主缓å˜" #: builtin/commit.c -msgid "unable to write new_index file" -msgstr "æ— æ³•å†™ new_index 文件" - -#: builtin/commit.c msgid "cannot do a partial commit during a merge." msgstr "在åˆå¹¶è¿‡ç¨‹ä¸ä¸èƒ½åšéƒ¨åˆ†æäº¤ã€‚" @@ -6260,10 +6282,10 @@ msgstr "å› æäº¤è¯´æ˜Žçš„æ£æ–‡ä¸ºç©ºè€Œç»ˆæ¢æäº¤ã€‚\n" #: builtin/commit.c msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" -"ä»“åº“å·²æ›´æ–°ï¼Œä½†æ— æ³•å†™ new_index 文件。检查是å¦ç£ç›˜å·²æ»¡æˆ–\n" +"ä»“åº“å·²æ›´æ–°ï¼Œä½†æ— æ³•å†™å…¥ç´¢å¼•æ–‡ä»¶ã€‚æ£€æŸ¥æ˜¯å¦ç£ç›˜å·²æ»¡æˆ–\n" "ç£ç›˜é…é¢å·²è€—å°½ï¼Œç„¶åŽæ‰§è¡Œ \"git restore --staged :/\" æ¢å¤ã€‚" #: builtin/config.c @@ -8070,6 +8092,10 @@ msgstr "清除未引用的对象" msgid "pack unreferenced objects separately" msgstr "分开打包未引用的对象" +#: builtin/gc.c builtin/repack.c +msgid "with --cruft, limit the size of new cruft packs" +msgstr "使用 --cruft,é™åˆ¶æ–° cruft 包的总大å°" + #: builtin/gc.c msgid "be more thorough (increased runtime)" msgstr "æ›´å½»åº•ï¼ˆå¢žåŠ è¿è¡Œæ—¶é—´ï¼‰" @@ -8285,14 +8311,6 @@ msgstr "æ— æ³•è¿è¡Œ 'crontab',您的系统å¯èƒ½ä¸æ”¯æŒ 'cron'" msgid "'crontab' died" msgstr "'crontab' 终æ¢" -#: builtin/gc.c -msgid "failed to start systemctl" -msgstr "æ— æ³•å¯åЍ systemctl" - -#: builtin/gc.c -msgid "failed to run systemctl" -msgstr "æ— æ³•è¿è¡Œ systemctl" - #: builtin/gc.c builtin/worktree.c #, c-format msgid "failed to delete '%s'" @@ -8304,6 +8322,14 @@ msgid "failed to flush '%s'" msgstr "æ— æ³•åˆ·æ–° '%s'" #: builtin/gc.c +msgid "failed to start systemctl" +msgstr "æ— æ³•å¯åЍ systemctl" + +#: builtin/gc.c +msgid "failed to run systemctl" +msgstr "æ— æ³•è¿è¡Œ systemctl" + +#: builtin/gc.c #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "æ— æ³•è¯†åˆ«çš„ --scheduler 傿•° '%s'" @@ -8334,6 +8360,10 @@ msgid "scheduler to trigger git maintenance run" msgstr "è§¦å‘ git maintenance 执行的调度器" #: builtin/gc.c +msgid "failed to set up maintenance schedule" +msgstr "æ— æ³•è®¾ç½®ç»´æŠ¤è®¡åˆ’" + +#: builtin/gc.c msgid "failed to add repo to global config" msgstr "æ— æ³•å°†ä»“åº“æ·»åŠ åˆ°å…¨å±€é…ç½®" @@ -8372,6 +8402,11 @@ msgstr "æ— æ³•è¯»å–æ ‘(%s)" #: builtin/grep.c #, c-format +msgid "unable to read tree %s" +msgstr "æ— æ³•è¯»å–æ ‘ %s" + +#: builtin/grep.c +#, c-format msgid "unable to grep from object of type %s" msgstr "æ— æ³•æŠ“å–æ¥è‡ªäºŽ %s 类型的对象" @@ -8429,8 +8464,8 @@ msgid "search in subdirectories (default)" msgstr "在å目录ä¸å¯»æ‰¾ï¼ˆé»˜è®¤ï¼‰" #: builtin/grep.c -msgid "descend at most <depth> levels" -msgstr "最多以指定的深度å‘下寻找" +msgid "descend at most <n> levels" +msgstr "最多å‘下寻找 <n> 层" #: builtin/grep.c msgid "use extended POSIX regular expressions" @@ -8893,11 +8928,6 @@ msgstr "解压缩严é‡çš„ä¸ä¸€è‡´" msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "å‘现 %s 出现 SHA1 冲çªï¼" -#: builtin/index-pack.c builtin/pack-objects.c -#, c-format -msgid "unable to read %s" -msgstr "ä¸èƒ½è¯» %s" - #: builtin/index-pack.c #, c-format msgid "cannot read existing object info %s" @@ -9075,11 +9105,13 @@ msgstr "åœ¨æ‰“åŒ…å¯¹è±¡ä¸ fsck 检查出错" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" "git init [-q | --quiet] [--bare] [--template=<模æ¿ç›®å½•>]\n" " [--separate-git-dir <git 目录>] [--object-format=<æ ¼å¼>]\n" +" [--ref-format=<æ ¼å¼>]\n" " [-b <分支å> | --initial-branch=<分支å>]\n" " [--shared[=<æƒé™>]] [<目录>]" @@ -9132,11 +9164,11 @@ msgstr "--separate-git-dir ä¸èƒ½ç”¨äºŽçº¯ä»“库" #: builtin/interpret-trailers.c msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <é”®>[(=|:)<值>])...]\n" +" [(--trailer (<é”®|键别å>)[(=|:)<值>])...]\n" " [--parse] [<文件>...]" #: builtin/interpret-trailers.c @@ -9148,6 +9180,10 @@ msgid "trim empty trailers" msgstr "åˆ é™¤ç©ºçš„å°¾æ³¨" #: builtin/interpret-trailers.c +msgid "placement" +msgstr "安置" + +#: builtin/interpret-trailers.c msgid "where to place the new trailer" msgstr "在哪里放置新的尾注" @@ -9164,20 +9200,20 @@ msgid "output only the trailers" msgstr "åªè¾“出尾注" #: builtin/interpret-trailers.c -msgid "do not apply config rules" -msgstr "ä¸è¦åº”用é…置规则" +msgid "do not apply trailer.* configuration variables" +msgstr "ä¸åº”用 trailer.* é…ç½®å˜é‡" #: builtin/interpret-trailers.c -msgid "join whitespace-continued values" -msgstr "连接空白折行的值" +msgid "reformat multiline trailer values as single-line values" +msgstr "å°†å¤šè¡Œå°¾æ³¨å€¼é‡æ–°æ ¼å¼åŒ–为å•行值" #: builtin/interpret-trailers.c -msgid "set parsing options" -msgstr "设置解æžé€‰é¡¹" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "--only-trailers --only-input --unfold 的别å" #: builtin/interpret-trailers.c -msgid "do not treat --- specially" -msgstr "ä¸è¦å¯¹ --- 特殊处ç†" +msgid "do not treat \"---\" as the end of input" +msgstr "ä¸è¦å°† \"---\" 视为输入的结æŸ" #: builtin/interpret-trailers.c msgid "trailer(s) to add" @@ -9234,7 +9270,7 @@ msgid "" "<file>" msgstr "跟踪 <文件> ä¸ <开始>,<结æŸ> 范围内的行或函数 :<函数å> 的演å˜" -#: builtin/log.c builtin/shortlog.c bundle.c +#: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c #, c-format msgid "unrecognized argument: %s" msgstr "æœªèƒ½è¯†åˆ«çš„å‚æ•°ï¼š%s" @@ -9290,6 +9326,11 @@ msgid "not a range" msgstr "䏿˜¯ä¸€ä¸ªèŒƒå›´" #: builtin/log.c +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "æ— æ³•è¯»å–分支æè¿°æ–‡ä»¶ '%s'" + +#: builtin/log.c msgid "cover letter needs email format" msgstr "附函需è¦é‚®ä»¶åœ°å€æ ¼å¼" @@ -9416,6 +9457,10 @@ msgid "generate parts of a cover letter based on a branch's description" msgstr "基于一个分支æè¿°ç”Ÿæˆéƒ¨åˆ†é™„函" #: builtin/log.c +msgid "use branch description from file" +msgstr "使用æ¥è‡ªæ–‡ä»¶çš„分支æè¿°" + +#: builtin/log.c msgid "use [<prefix>] instead of [PATCH]" msgstr "使用 [<å‰ç¼€>] 代替 [PATCH]" @@ -9969,11 +10014,21 @@ msgstr "" "git merge-file [<选项>] [-L <åå—1> [-L <åˆå§‹åå—> [-L <åå—2>]]] <文件1> <åˆ" "始文件> <文件2>" +#: builtin/merge-file.c diff.c +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "选项 diff-algorithm 接å—傿•° \"myers\"ã€\"minimal\"ã€\"patience\" å’Œ \"histogram\"" + #: builtin/merge-file.c msgid "send results to standard output" msgstr "将结果å‘é€åˆ°æ ‡å‡†è¾“出" #: builtin/merge-file.c +msgid "use object IDs instead of filenames" +msgstr "使用对象 ID æ›¿æ¢æ–‡ä»¶å" + +#: builtin/merge-file.c msgid "use a diff3 based merge" msgstr "使用基于 diff3 çš„åˆå¹¶" @@ -9993,6 +10048,14 @@ msgstr "如果冲çªï¼Œä½¿ç”¨ä»–们的版本" msgid "for conflicts, use a union version" msgstr "如果冲çªï¼Œä½¿ç”¨è”åˆç‰ˆæœ¬" +#: builtin/merge-file.c diff.c +msgid "<algorithm>" +msgstr "<算法>" + +#: builtin/merge-file.c diff.c +msgid "choose a diff algorithm" +msgstr "选择一个差异算法" + #: builtin/merge-file.c msgid "for conflicts, use this marker size" msgstr "如果冲çªï¼Œä½¿ç”¨æŒ‡å®šé•¿åº¦çš„æ ‡è®°" @@ -10005,6 +10068,15 @@ msgstr "ä¸è¦è¦å‘Šå†²çª" msgid "set labels for file1/orig-file/file2" msgstr "为 文件1/åˆå§‹æ–‡ä»¶/文件2 è®¾ç½®æ ‡ç¾" +#: builtin/merge-file.c +#, c-format +msgid "object '%s' does not exist" +msgstr "对象 '%s' ä¸å˜åœ¨" + +#: builtin/merge-file.c +msgid "Could not write object file" +msgstr "ä¸èƒ½å†™å…¥å¯¹è±¡æ–‡ä»¶" + #: builtin/merge-recursive.c #, c-format msgid "unknown option %s" @@ -10084,13 +10156,22 @@ msgstr "实施多个åˆå¹¶ï¼Œæ¯è¾“入行一个" msgid "specify a merge-base for the merge" msgstr "指定用于åˆå¹¶çš„åˆå¹¶åŸºçº¿" +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c +msgid "option=value" +msgstr "option=value" + +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c +msgid "option for selected merge strategy" +msgstr "所选的åˆå¹¶ç–略的选项" + #: builtin/merge-tree.c msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge 与其他所有选项ä¸å…¼å®¹" -#: builtin/merge-tree.c -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base 与 --stdin ä¸å…¼å®¹" +#: builtin/merge-tree.c builtin/merge.c +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "未知的ç–略选项:-X%s" #: builtin/merge-tree.c builtin/notes.c #, c-format @@ -10179,14 +10260,6 @@ msgstr "ç–ç•¥" msgid "merge strategy to use" msgstr "è¦ä½¿ç”¨çš„åˆå¹¶ç–ç•¥" -#: builtin/merge.c builtin/pull.c -msgid "option=value" -msgstr "option=value" - -#: builtin/merge.c builtin/pull.c -msgid "option for selected merge strategy" -msgstr "所选的åˆå¹¶ç–略的选项" - #: builtin/merge.c msgid "merge commit message (for a non-fast-forward merge)" msgstr "åˆå¹¶çš„æäº¤è¯´æ˜Žï¼ˆé’ˆå¯¹éžå¿«è¿›å¼åˆå¹¶ï¼‰" @@ -10257,7 +10330,7 @@ msgstr "'%s' 没有指å‘一个æäº¤" msgid "Bad branch.%s.mergeoptions string: %s" msgstr "åçš„ branch.%s.mergeoptions å—符串:%s" -#: builtin/merge.c builtin/stash.c merge-recursive.c +#: builtin/merge.c merge-recursive.c msgid "Unable to write index." msgstr "ä¸èƒ½å†™å…¥ç´¢å¼•。" @@ -10267,11 +10340,6 @@ msgstr "未处ç†ä¸¤ä¸ªå¤´åˆå¹¶ä¹‹å¤–的任何æ“作。" #: builtin/merge.c #, c-format -msgid "unknown strategy option: -X%s" -msgstr "未知的ç–略选项:-X%s" - -#: builtin/merge.c t/helper/test-fast-rebase.c -#, c-format msgid "unable to write %s" msgstr "ä¸èƒ½å†™ %s" @@ -10628,8 +10696,8 @@ msgid "can not move directory into itself" msgstr "ä¸èƒ½å°†ç›®å½•移动到自身" #: builtin/mv.c -msgid "cannot move directory over file" -msgstr "ä¸èƒ½å°†ç›®å½•移动到文件" +msgid "destination already exists" +msgstr "ç›®æ ‡å·²å˜åœ¨" #: builtin/mv.c msgid "source directory is empty" @@ -11258,6 +11326,11 @@ msgstr "ä¸ä¸€è‡´çš„差异计数" #: builtin/pack-objects.c #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "æ— æ•ˆçš„ pack.allowPackReuse 值:'%s'" + +#: builtin/pack-objects.c +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -11557,10 +11630,6 @@ msgid "--thin cannot be used to build an indexable pack" msgstr "--thin ä¸èƒ½ç”¨äºŽåˆ›å»ºä¸€ä¸ªå¯ç´¢å¼•包" #: builtin/pack-objects.c -msgid "cannot use --filter without --stdout" -msgstr "ä¸èƒ½åœ¨æ²¡æœ‰ --stdout 的情况下使用 --filter" - -#: builtin/pack-objects.c msgid "cannot use --filter with --stdin-packs" msgstr "ä¸èƒ½åŒæ—¶ä½¿ç”¨ --filter å’Œ --stdin-packs" @@ -11577,10 +11646,6 @@ msgid "cannot use --stdin-packs with --cruft" msgstr "ä¸èƒ½å°† --stdin-packs å’Œ --cruft åŒæ—¶ä½¿ç”¨" #: builtin/pack-objects.c -msgid "cannot use --max-pack-size with --cruft" -msgstr "ä¸èƒ½å°† --max-pack-size å’Œ --cruft åŒæ—¶ä½¿ç”¨" - -#: builtin/pack-objects.c msgid "Enumerating objects" msgstr "枚举对象ä¸" @@ -11588,10 +11653,10 @@ msgstr "枚举对象ä¸" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "总共 %<PRIu32>(差异 %<PRIu32>),å¤ç”¨ %<PRIu32>(差异 %<PRIu32>),包å¤ç”¨ " -"%<PRIu32>" +"%<PRIu32>(æ¥è‡ª %<PRIuMAX> 个包)" #: builtin/pack-redundant.c msgid "" @@ -12665,7 +12730,7 @@ msgstr "没有æ£åœ¨è¿›è¡Œçš„å˜åŸºï¼Ÿ" msgid "The --edit-todo action can only be used during interactive rebase." msgstr "动作 --edit-todo åªèƒ½ç”¨åœ¨äº¤äº’å¼å˜åŸºè¿‡ç¨‹ä¸ã€‚" -#: builtin/rebase.c t/helper/test-fast-rebase.c +#: builtin/rebase.c msgid "Cannot read HEAD" msgstr "ä¸èƒ½è¯»å– HEAD" @@ -12710,16 +12775,6 @@ msgid "switch `C' expects a numerical value" msgstr "开关 `C' 期望一个数å—值" #: builtin/rebase.c -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy éœ€è¦ --merge 或 --interactive" - -#: builtin/rebase.c -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "应用的选项与 rebase.autoSquash ä¸å…¼å®¹ã€‚è€ƒè™‘åŠ ä¸Š --no-autosquash" - -#: builtin/rebase.c msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -13202,8 +13257,8 @@ msgid "" msgid_plural "" "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n" "to delete them, use:" -msgstr[0] "注æ„:ref/remotes 层级之外的一个分支未被移除。è¦åˆ 除它,使用:" -msgstr[1] "注æ„:ref/remotes 层级之外的一些分支未被移除。è¦åˆ 除它们,使用:" +msgstr[0] "注æ„:refs/remotes/ 层级之外的一个分支未被移除。è¦åˆ 除它,使用:" +msgstr[1] "注æ„:refs/remotes/ 层级之外的一些分支未被移除。è¦åˆ 除它们,使用:" #: builtin/remote.c #, c-format @@ -13562,6 +13617,11 @@ msgid "could not remove stale bitmap: %s" msgstr "æ— æ³•åˆ é™¤è¿‡æœŸçš„ä½å›¾ï¼š %s" #: builtin/repack.c +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "包å‰ç¼€ %s 没有以对象目录 %s 开始" + +#: builtin/repack.c msgid "pack everything in a single pack" msgstr "所有内容打包到一个包文件ä¸" @@ -13662,17 +13722,21 @@ msgid "pack prefix to store a pack containing pruned objects" msgstr "储å˜è¢«æ¸…除的对象的包的å‰ç¼€" #: builtin/repack.c +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "储å˜è¢«è¿‡æ»¤çš„对象的包的å‰ç¼€" + +#: builtin/repack.c msgid "cannot delete packs in a precious-objects repo" msgstr "ä¸èƒ½åˆ 除çå“仓库ä¸çš„æ‰“包文件" #: builtin/repack.c -msgid "Nothing new to pack." -msgstr "æ²¡æœ‰æ–°çš„è¦æ‰“包。" +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "选项 '%s' åªèƒ½å’Œ '%s' æé…使用" #: builtin/repack.c -#, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "包å‰ç¼€ %s 没有以对象目录 .%s 开始" +msgid "Nothing new to pack." +msgstr "æ²¡æœ‰æ–°çš„è¦æ‰“包。" #: builtin/repack.c #, c-format @@ -13925,6 +13989,84 @@ msgstr "--convert-graft-file ä¸å¸¦å‚æ•°" msgid "only one pattern can be given with -l" msgstr "åªèƒ½ä¸º -l æä¾›ä¸€ä¸ªæ¨¡å¼" +#: builtin/replay.c +msgid "need some commits to replay" +msgstr "需è¦ä¸€äº›æäº¤æ¥é‡æ”¾" + +#: builtin/replay.c +msgid "--onto and --advance are incompatible" +msgstr "--onto å’Œ --advance ä¸å…¼å®¹" + +#: builtin/replay.c +msgid "all positive revisions given must be references" +msgstr "æä¾›çš„æ‰€æœ‰æ£å‘版本必须为引用" + +#: builtin/replay.c +msgid "argument to --advance must be a reference" +msgstr "--advance çš„å‚æ•°å¿…须是引用" + +#: builtin/replay.c +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "ä¸èƒ½ä½¿ç”¨å¤šä¸ªæºæŽ¨è¿›ç›®æ ‡ï¼Œå› ä¸ºæ— æ³•æ˜Žç¡®å¦‚ä½•æŽ’åº" + +#: builtin/replay.c +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "ä¸èƒ½éšå¼åœ°ç¡®å®šè¿™æ˜¯ --advance 还是 --onto çš„æ“作" + +#: builtin/replay.c +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "ä¸èƒ½ä½¿ç”¨å¤šä¸ªæºåˆ†æ”¯æŽ¨è¿›ç›®æ ‡ï¼Œå› ä¸ºæ— æ³•æ˜Žç¡®å¦‚ä½•æŽ’åº" + +#: builtin/replay.c +msgid "cannot implicitly determine correct base for --onto" +msgstr "ä¸èƒ½éšå¼åœ°ç¡®å®š --onto æ£ç¡®çš„基线" + +#: builtin/replay.c +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "(试验ä¸ï¼ï¼‰git replay ([--contained] --onto <新基线> | --advance <分支>) <版本范围>..." + +#: builtin/replay.c +msgid "make replay advance given branch" +msgstr "釿”¾æ—¶æ¼”进给定的分支" + +#: builtin/replay.c +msgid "replay onto given commit" +msgstr "釿”¾åˆ°ç»™å®šæäº¤" + +#: builtin/replay.c +msgid "advance all branches contained in revision-range" +msgstr "演进版本范围ä¸åŒ…å«çš„æ‰€æœ‰åˆ†æ”¯" + +#: builtin/replay.c +msgid "option --onto or --advance is mandatory" +msgstr "选项 --onto 或 --advance 必须指定其一" + +#: builtin/replay.c +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "一些版本é历选项将被覆盖,如 'struct rev_info' ä¸çš„ '%s' ä½å°†è¢«å¼ºåˆ¶è®¾å®š" + +#: builtin/replay.c +msgid "error preparing revisions" +msgstr "准备版本时错误" + +#: builtin/replay.c +msgid "replaying down to root commit is not supported yet!" +msgstr "ç›®å‰è¿˜ä¸æ”¯æŒé‡æ”¾åˆ°æ ¹æäº¤ï¼" + +#: builtin/replay.c +msgid "replaying merge commits is not supported yet!" +msgstr "ç›®å‰è¿˜ä¸æ”¯æŒé‡æ”¾åˆ°åˆå¹¶æäº¤ï¼" + #: builtin/rerere.c msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" @@ -14184,23 +14326,15 @@ msgstr "--prefix 需è¦ä¸€ä¸ªå‚æ•°" msgid "unknown mode for --abbrev-ref: %s" msgstr "未知的 --abbrev-ref 模å¼ï¼š%s" -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden ä¸èƒ½ä¸Ž --branches 一起使用" - -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden ä¸èƒ½ä¸Ž --tags 一起使用" - -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden ä¸èƒ½ä¸Ž --remotes 一起使用" - #: builtin/rev-parse.c setup.c msgid "this operation must be run in a work tree" msgstr "该æ“作必须在一个工作区ä¸è¿è¡Œ" #: builtin/rev-parse.c +msgid "Could not read the index" +msgstr "ä¸èƒ½è¯»å–索引" + +#: builtin/rev-parse.c #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "未知的 --show-object-format 模å¼ï¼š%s" @@ -14625,19 +14759,41 @@ msgstr "未知的哈希算法" #: builtin/show-ref.c msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<模å¼>...]" #: builtin/show-ref.c +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<引用>...]" + +#: builtin/show-ref.c msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<模å¼>]" #: builtin/show-ref.c +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <引用>" + +#: builtin/show-ref.c +msgid "reference does not exist" +msgstr "引用ä¸å˜åœ¨" + +#: builtin/show-ref.c +msgid "failed to look up reference" +msgstr "æ— æ³•æ‰¾åˆ°å¼•ç”¨" + +#: builtin/show-ref.c msgid "only show tags (can be combined with heads)" msgstr "åªæ˜¾ç¤ºæ ‡ç¾ï¼ˆå¯ä»¥å’Œå¤´å…±ç”¨ï¼‰" @@ -14646,6 +14802,10 @@ msgid "only show heads (can be combined with tags)" msgstr "åªæ˜¾ç¤ºå¤´ï¼ˆå¯ä»¥å’Œæ ‡ç¾å…±ç”¨ï¼‰" #: builtin/show-ref.c +msgid "check for reference existence without resolving" +msgstr "检查引用是å¦å˜åœ¨ä½†ä¸è§£æž" + +#: builtin/show-ref.c msgid "stricter reference checking, requires exact ref path" msgstr "æ›´ä¸¥æ ¼çš„å¼•ç”¨æ£€æµ‹ï¼Œéœ€è¦ç²¾ç¡®çš„引用路径" @@ -15631,6 +15791,10 @@ msgstr "" "shallow] [--reference <仓库>] [--recursive] [--[no-]single-branch] [--] [<è·¯" "径>...]" +#: builtin/submodule--helper.c submodule.c +msgid "Failed to resolve HEAD as a valid ref." +msgstr "æ— æ³•å°† HEAD è§£æžä¸ºæœ‰æ•ˆå¼•用。" + #: builtin/submodule--helper.c msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<选项>] [<路径>...]" @@ -16207,6 +16371,10 @@ msgid "write index in this format" msgstr "ä»¥è¿™ç§æ ¼å¼å†™å…¥ç´¢å¼•区" #: builtin/update-index.c +msgid "report on-disk index format version" +msgstr "报告ç£ç›˜ç´¢å¼•æ ¼å¼çš„版本" + +#: builtin/update-index.c msgid "enable or disable split index" msgstr "å¯ç”¨æˆ–ç¦ç”¨ç´¢å¼•拆分" @@ -16239,6 +16407,16 @@ msgid "clear fsmonitor valid bit" msgstr "清除 fsmonitor 有效ä½" #: builtin/update-index.c +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#: builtin/update-index.c +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "索引版本:从 %d 设置为 %d" + +#: builtin/update-index.c msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -16425,30 +16603,30 @@ msgstr "没有å¯ç”¨çš„æºåˆ†æ”¯ï¼Œå°†åŸºäºŽ '--orphan' 选项进行推æ–" #: builtin/worktree.c #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan -b %s %s\n" msgstr "" -"å¦‚æžœä½ æ‰“ç®—ä¸ºæ¤ä»“åº“åˆ›å»ºä¸€ä¸ªåŒ…å«æ–°çš„å¤ç«‹åˆ†æ”¯\n" -"(没有æäº¤çš„åˆ†æ”¯ï¼‰çš„å·¥ä½œåŒºï¼Œä½ å¯ä»¥ä½¿ç”¨é€‰é¡¹\n" -"--orphan æ¥æ‰§è¡Œæ¤æ“作:\n" +"å¦‚æžœä½ æ‰“ç®—ä¸ºæ¤ä»“åº“åˆ›å»ºä¸€ä¸ªåŒ…å«æ–°çš„æœªè¯žç”Ÿçš„\n" +"分支(没有æäº¤çš„åˆ†æ”¯ï¼‰çš„å·¥ä½œåŒºï¼Œä½ å¯ä»¥ä½¿ç”¨\n" +"选项 --orphan æ¥æ‰§è¡Œæ¤æ“作:\n" "\n" " git worktree add --orphan -b %s %s\n" #: builtin/worktree.c #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan %s\n" msgstr "" -"å¦‚æžœä½ æ‰“ç®—ä¸ºæ¤ä»“åº“åˆ›å»ºä¸€ä¸ªåŒ…å«æ–°çš„å¤ç«‹åˆ†æ”¯\n" -"(没有æäº¤çš„åˆ†æ”¯ï¼‰çš„å·¥ä½œåŒºï¼Œä½ å¯ä»¥ä½¿ç”¨é€‰é¡¹\n" -"--orphan æ¥æ‰§è¡Œæ¤æ“作:\n" +"å¦‚æžœä½ æ‰“ç®—ä¸ºæ¤ä»“åº“åˆ›å»ºä¸€ä¸ªåŒ…å«æ–°çš„æœªè¯žç”Ÿçš„\n" +"分支(没有æäº¤çš„åˆ†æ”¯ï¼‰çš„å·¥ä½œåŒºï¼Œä½ å¯ä»¥ä½¿ç”¨\n" +"选项 --orphan æ¥æ‰§è¡Œæ¤æ“作:\n" "\n" " git worktree add --orphan %s\n" @@ -16519,6 +16697,11 @@ msgstr "åˆå§‹åŒ–" #: builtin/worktree.c #, c-format +msgid "could not find created worktree '%s'" +msgstr "æ— æ³•æ‰¾åˆ°å·²åˆ›å»ºçš„å·¥ä½œæ ‘ '%s'" + +#: builtin/worktree.c +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "准备工作区(新分支 '%s')" @@ -16556,15 +16739,10 @@ msgstr "" #: builtin/worktree.c msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" -"尽管已é…置远程仓库,但ä¸å˜åœ¨ä»»ä½•本地的或远程的引用,æ“作终æ¢;\n" -"请使用 'add -f' æ¥è¦†ç›–或拉å–一个远程仓库" - -#: builtin/worktree.c -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "'%s' å’Œ '%s' ä¸èƒ½åŒæ—¶ä½¿ç”¨" +"尽管已é…置远程仓库,但ä¸å˜åœ¨ä»»ä½•本地的或远程的引用,æ“作终æ¢ã€‚\n" +"请先使用 'add -f' æ¥è¦†ç›–或拉å–一个远程仓库" #: builtin/worktree.c msgid "checkout <branch> even if already checked out in other worktree" @@ -16579,8 +16757,8 @@ msgid "create or reset a branch" msgstr "创建或é‡ç½®ä¸€ä¸ªåˆ†æ”¯" #: builtin/worktree.c -msgid "create unborn/orphaned branch" -msgstr "创建一个尚未诞生的/å¤ç«‹çš„分支" +msgid "create unborn branch" +msgstr "创建一个尚未诞生的分支" #: builtin/worktree.c msgid "populate the new working tree" @@ -16609,12 +16787,8 @@ msgstr "选项 '%s'ã€'%s' å’Œ '%s' ä¸èƒ½åŒæ—¶ä½¿ç”¨" #: builtin/worktree.c #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "选项 '%s',与 '%s' ä¸èƒ½åŒæ—¶ä½¿ç”¨" - -#: builtin/worktree.c -msgid "<commit-ish>" -msgstr "<æäº¤å·>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "选项 '%s' å’Œæäº¤å·ä¸èƒ½åŒæ—¶ä½¿ç”¨" #: builtin/worktree.c msgid "added with --lock" @@ -16952,6 +17126,11 @@ msgstr "终æ¢å— ID 比预期更早出现" #: chunk-format.c #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "å— id %<PRIx32> 未 %d å—节对é½" + +#: chunk-format.c +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "䏿£ç¡®çš„å—åç§» %<PRIx64> å’Œ %<PRIx64>" @@ -17019,8 +17198,8 @@ msgid "Move objects and refs by archive" msgstr "通过归档移动对象和引用" #: command-list.h -msgid "Provide content or type and size information for repository objects" -msgstr "æä¾›ä»“库对象的内容ã€ç±»åž‹æˆ–大å°" +msgid "Provide contents or details of repository objects" +msgstr "æä¾›ä»“库对象的内容或详情" #: command-list.h msgid "Display gitattributes information" @@ -17400,6 +17579,10 @@ msgid "Create, list, delete refs to replace objects" msgstr "创建ã€åˆ—出ã€åˆ 除对象替æ¢å¼•用" #: command-list.h +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "试验ä¸ï¼šåŸºäºŽä¸€ä¸ªæ–°åŸºçº¿é‡æ”¾æäº¤ï¼ŒåŒæ ·é€‚用于纯仓库" + +#: command-list.h msgid "Generates a summary of pending changes" msgstr "生æˆå¾…定更改的摘è¦" @@ -17561,7 +17744,7 @@ msgid "Display version information about Git" msgstr "显示关于 Git 的版本信æ¯" #: command-list.h -msgid "Show logs with difference each commit introduces" +msgid "Show logs with differences each commit introduces" msgstr "显示æ¯ä¸€ä¸ªæäº¤å¼•入的差异日志" #: command-list.h @@ -17714,35 +17897,82 @@ msgstr "一个管ç†å¤§åž‹ Git 仓库的工具" #: commit-graph.c msgid "commit-graph file is too small" -msgstr "æäº¤å›¾å½¢æ–‡ä»¶å¤ªå°" +msgstr "æäº¤å›¾æ–‡ä»¶å¤ªå°" + +#: commit-graph.c +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "æäº¤å›¾ä¸å¯¹è±¡ ID 的扇出å—大å°é”™è¯¯" + +#: commit-graph.c +msgid "commit-graph fanout values out of order" +msgstr "æäº¤å›¾çš„æ‰‡å‡ºå€¼å¤±åº" + +#: commit-graph.c +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "æäº¤å›¾çš„对象 ID 查询å—大å°é”™è¯¯" + +#: commit-graph.c +msgid "commit-graph commit data chunk is wrong size" +msgstr "æäº¤å›¾çš„æäº¤æ•°æ®å—大å°é”™è¯¯" + +#: commit-graph.c +msgid "commit-graph generations chunk is wrong size" +msgstr "æäº¤å›¾çš„世代å—大å°é”™è¯¯" + +#: commit-graph.c +msgid "commit-graph changed-path index chunk is too small" +msgstr "æäº¤å›¾çš„å˜æ›´è·¯å¾„的索引å—太å°" + +#: commit-graph.c +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "忽略æäº¤å›¾æ–‡ä»¶ä¸è¿‡å°çš„æ›´æ”¹è·¯å¾„å—(%<PRIuMAX> < %<PRIuMAX>)" #: commit-graph.c #, c-format msgid "commit-graph signature %X does not match signature %X" -msgstr "æäº¤å›¾å½¢ç¾å %X å’Œç¾å %X ä¸åŒ¹é…" +msgstr "æäº¤å›¾ç¾å %X å’Œç¾å %X ä¸åŒ¹é…" #: commit-graph.c #, c-format msgid "commit-graph version %X does not match version %X" -msgstr "æäº¤å›¾å½¢ç‰ˆæœ¬ %X 和版本 %X ä¸åŒ¹é…" +msgstr "æäº¤å›¾ç‰ˆæœ¬ %X 和版本 %X ä¸åŒ¹é…" #: commit-graph.c #, c-format msgid "commit-graph hash version %X does not match version %X" -msgstr "æäº¤å›¾å½¢å“ˆå¸Œç‰ˆæœ¬ %X 和版本 %X ä¸åŒ¹é…" +msgstr "æäº¤å›¾å“ˆå¸Œç‰ˆæœ¬ %X 和版本 %X ä¸åŒ¹é…" #: commit-graph.c #, c-format msgid "commit-graph file is too small to hold %u chunks" -msgstr "æäº¤å›¾å½¢æ–‡ä»¶å¤ªå°ï¼Œå®¹ä¸ä¸‹ %u 个å—" +msgstr "æäº¤å›¾æ–‡ä»¶å¤ªå°ï¼Œå®¹ä¸ä¸‹ %u 个å—" + +#: commit-graph.c +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "æäº¤å›¾æ‰€éœ€çš„对象 ID 扇出å—缺失或æŸå" + +#: commit-graph.c +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "æäº¤å›¾æ‰€éœ€çš„对象 ID 查询å—缺失或æŸå" + +#: commit-graph.c +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "æäº¤å›¾æ‰€éœ€çš„æäº¤æ•°æ®å—缺失或æŸå" #: commit-graph.c msgid "commit-graph has no base graphs chunk" -msgstr "æäº¤å›¾å½¢æ²¡æœ‰åŸºç¡€å›¾å½¢å—" +msgstr "æäº¤å›¾æ²¡æœ‰åŸºç¡€å›¾å½¢å—" + +#: commit-graph.c +msgid "commit-graph base graphs chunk is too small" +msgstr "æäº¤å›¾çš„基础图形å—过å°" #: commit-graph.c msgid "commit-graph chain does not match" -msgstr "æäº¤å›¾å½¢é“¾ä¸åŒ¹é…" +msgstr "æäº¤å›¾é“¾ä¸åŒ¹é…" #: commit-graph.c #, c-format @@ -17750,17 +17980,21 @@ msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "基础图形ä¸çš„æäº¤æ•°é‡è¿‡é«˜ï¼š%<PRIuMAX>" #: commit-graph.c +msgid "commit-graph chain file too small" +msgstr "æäº¤å›¾é“¾æ–‡ä»¶å¤ªå°" + +#: commit-graph.c #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" -msgstr "æ— æ•ˆçš„æäº¤å›¾å½¢é“¾ï¼šè¡Œ '%s' 䏿˜¯ä¸€ä¸ªå“ˆå¸Œå€¼" +msgstr "æ— æ•ˆçš„æäº¤å›¾é“¾ï¼šè¡Œ '%s' 䏿˜¯ä¸€ä¸ªå“ˆå¸Œå€¼" #: commit-graph.c msgid "unable to find all commit-graph files" -msgstr "æ— æ³•æ‰¾åˆ°æ‰€æœ‰æäº¤å›¾å½¢æ–‡ä»¶" +msgstr "æ— æ³•æ‰¾åˆ°æ‰€æœ‰æäº¤å›¾æ–‡ä»¶" #: commit-graph.c msgid "invalid commit position. commit-graph is likely corrupt" -msgstr "æ— æ•ˆçš„æäº¤ä½ç½®ã€‚æäº¤å›¾å½¢å¯èƒ½å·²æŸå" +msgstr "æ— æ•ˆçš„æäº¤ä½ç½®ã€‚æäº¤å›¾å¯èƒ½å·²æŸå" #: commit-graph.c #, c-format @@ -17772,6 +18006,14 @@ msgid "commit-graph requires overflow generation data but has none" msgstr "æäº¤å›¾éœ€è¦æº¢å‡ºä¸–代数æ®ï¼Œä½†æ˜¯æ²¡æœ‰" #: commit-graph.c +msgid "commit-graph overflow generation data is too small" +msgstr "æäº¤å›¾æº¢å‡ºä¸–代数æ®è¿‡å°" + +#: commit-graph.c +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "æäº¤å›¾é¢å¤–边的指针越界" + +#: commit-graph.c msgid "Loading known commits in commit graph" msgstr "æ£åœ¨åŠ è½½æäº¤å›¾ä¸çš„已知æäº¤" @@ -17846,26 +18088,25 @@ msgstr[1] "æ£åœ¨ç”¨ %d æ¥å†™å‡ºæäº¤å›¾" #: commit-graph.c msgid "unable to open commit-graph chain file" -msgstr "æ— æ³•æ‰“å¼€æäº¤å›¾å½¢é“¾æ–‡ä»¶" +msgstr "æ— æ³•æ‰“å¼€æäº¤å›¾é“¾æ–‡ä»¶" #: commit-graph.c msgid "failed to rename base commit-graph file" -msgstr "æ— æ³•é‡å‘½å基础æäº¤å›¾å½¢æ–‡ä»¶" +msgstr "æ— æ³•é‡å‘½å基础æäº¤å›¾æ–‡ä»¶" #: commit-graph.c msgid "failed to rename temporary commit-graph file" -msgstr "æ— æ³•é‡å‘½å临时æäº¤å›¾å½¢æ–‡ä»¶" +msgstr "æ— æ³•é‡å‘½å临时æäº¤å›¾æ–‡ä»¶" #: commit-graph.c #, c-format msgid "cannot merge graphs with %<PRIuMAX>, %<PRIuMAX> commits" -msgstr "" -"æ— æ³•åˆå¹¶æäº¤å›¾å½¢ï¼Œæ€»å…±å·²ç´¯åŠ æäº¤æ•°ï¼š%<PRIuMAX>,当å‰å¾…ç´¯åŠ æäº¤æ•°ï¼š%<PRIuMAX>" +msgstr "æ— æ³•åˆå¹¶æäº¤å›¾ï¼Œæ€»å…±å·²ç´¯åŠ æäº¤æ•°ï¼š%<PRIuMAX>,当å‰å¾…ç´¯åŠ æäº¤æ•°ï¼š%<PRIuMAX>" #: commit-graph.c #, c-format msgid "cannot merge graph %s, too many commits: %<PRIuMAX>" -msgstr "æ— æ³•åˆå¹¶æäº¤å›¾å½¢ %s, æäº¤è¿‡å¤šï¼š%<PRIuMAX>" +msgstr "æ— æ³•åˆå¹¶æäº¤å›¾ %s, æäº¤è¿‡å¤šï¼š%<PRIuMAX>" #: commit-graph.c msgid "Scanning merged commits" @@ -17873,7 +18114,7 @@ msgstr "æ£åœ¨æ‰«æåˆå¹¶æäº¤" #: commit-graph.c msgid "Merging commit-graph" -msgstr "æ£åœ¨åˆå¹¶æäº¤å›¾å½¢" +msgstr "æ£åœ¨åˆå¹¶æäº¤å›¾" #: commit-graph.c msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled" @@ -17890,64 +18131,59 @@ msgstr "æäº¤å›¾æ–‡ä»¶çš„æ ¡éªŒç 错误,å¯èƒ½å·²ç»æŸå" #: commit-graph.c #, c-format msgid "commit-graph has incorrect OID order: %s then %s" -msgstr "æäº¤å›¾å½¢çš„对象 ID 顺åºä¸æ£ç¡®ï¼š%s ç„¶åŽ %s" +msgstr "æäº¤å›¾çš„对象 ID 顺åºä¸æ£ç¡®ï¼š%s ç„¶åŽ %s" #: commit-graph.c #, c-format msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u" -msgstr "æäº¤å›¾å½¢æœ‰ä¸æ£ç¡®çš„æ‰‡å‡ºå€¼ï¼šfanout[%d] = %u != %u" +msgstr "æäº¤å›¾æœ‰ä¸æ£ç¡®çš„æ‰‡å‡ºå€¼ï¼šfanout[%d] = %u != %u" #: commit-graph.c #, c-format msgid "failed to parse commit %s from commit-graph" -msgstr "æ— æ³•ä»Žæäº¤å›¾å½¢ä¸è§£æžæäº¤ %s" +msgstr "æ— æ³•ä»Žæäº¤å›¾ä¸è§£æžæäº¤ %s" #: commit-graph.c #, c-format msgid "failed to parse commit %s from object database for commit-graph" -msgstr "æ— æ³•ä»Žæäº¤å›¾å½¢çš„对象库ä¸è§£æžæäº¤ %s" +msgstr "æ— æ³•ä»Žæäº¤å›¾çš„对象库ä¸è§£æžæäº¤ %s" #: commit-graph.c #, c-format msgid "root tree OID for commit %s in commit-graph is %s != %s" -msgstr "æäº¤å›¾å½¢ä¸çš„æäº¤ %s çš„æ ¹æ ‘å¯¹è±¡ ID 是 %s != %s" +msgstr "æäº¤å›¾ä¸çš„æäº¤ %s çš„æ ¹æ ‘å¯¹è±¡ ID 是 %s != %s" #: commit-graph.c #, c-format msgid "commit-graph parent list for commit %s is too long" -msgstr "æäº¤ %s çš„æäº¤å›¾å½¢çˆ¶æäº¤åˆ—表太长了" +msgstr "æäº¤ %s çš„æäº¤å›¾çˆ¶æäº¤åˆ—表太长了" #: commit-graph.c #, c-format msgid "commit-graph parent for %s is %s != %s" -msgstr "%s çš„æäº¤å›¾å½¢çˆ¶æäº¤æ˜¯ %s != %s" +msgstr "%s çš„æäº¤å›¾çˆ¶æäº¤æ˜¯ %s != %s" #: commit-graph.c #, c-format msgid "commit-graph parent list for commit %s terminates early" -msgstr "æäº¤ %s çš„æäº¤å›¾å½¢çˆ¶æäº¤åˆ—表过早终æ¢" - -#: commit-graph.c -#, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "æäº¤å›¾å½¢ä¸æäº¤ %s çš„ä¸–ä»£å·æ˜¯é›¶ï¼Œä½†å…¶å®ƒåœ°æ–¹éžé›¶" +msgstr "æäº¤ %s çš„æäº¤å›¾çˆ¶æäº¤åˆ—表过早终æ¢" #: commit-graph.c #, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "æäº¤å›¾å½¢ä¸æäº¤ %s 的世代å·éžé›¶ï¼Œä½†å…¶å®ƒåœ°æ–¹æ˜¯é›¶" +msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" +msgstr "æäº¤å›¾ä¸çš„æäº¤ %s çš„ä¸–ä»£å·æ˜¯ %<PRIuMAX> < %<PRIuMAX>" #: commit-graph.c #, c-format -msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" -msgstr "æäº¤å›¾å½¢ä¸çš„æäº¤ %s çš„ä¸–ä»£å·æ˜¯ %<PRIuMAX> < %<PRIuMAX>" +msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>" +msgstr "æäº¤å›¾ä¸æäº¤ %s çš„æäº¤æ—¥æœŸæ˜¯ %<PRIuMAX> != %<PRIuMAX>" #: commit-graph.c #, c-format -msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>" -msgstr "æäº¤å›¾å½¢ä¸æäº¤ %s çš„æäº¤æ—¥æœŸæ˜¯ %<PRIuMAX> != %<PRIuMAX>" +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "æäº¤å›¾å…·æœ‰é›¶å’Œéžé›¶çš„世代(例如:æäº¤ '%s' å’Œ '%s')" #: commit-graph.c msgid "Verifying commits in commit graph" @@ -17980,6 +18216,11 @@ msgstr "" #: commit.c #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "æäº¤ %s å˜åœ¨äºŽæäº¤å›¾ä¸ï¼Œä½†ä¸å˜åœ¨äºŽå¯¹è±¡æ•°æ®åº“ä¸" + +#: commit.c +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "æäº¤ %s 有一个éžå¯ä¿¡çš„声称æ¥è‡ª %s çš„ GPG ç¾å。" @@ -18522,11 +18763,6 @@ msgid "unable to resolve config blob '%s'" msgstr "ä¸èƒ½è§£æžé…置对象 '%s'" #: config.c -#, c-format -msgid "failed to parse %s" -msgstr "æ— æ³•è§£æž %s" - -#: config.c msgid "unable to parse command-line config" msgstr "æ— æ³•è§£æžå‘½ä»¤è¡Œä¸çš„é…ç½®" @@ -19094,10 +19330,6 @@ msgid "--merge-base does not work with ranges" msgstr "--merge-base ä¸é€‚用于范围" #: diff-lib.c -msgid "--merge-base only works with commits" -msgstr "--merge-base 仅适用于æäº¤" - -#: diff-lib.c msgid "unable to get HEAD" msgstr "ä¸èƒ½è§£æž HEAD" @@ -19167,6 +19399,11 @@ msgstr "color-moved-ws:allow-indentation-change ä¸èƒ½ä¸Žå…¶å®ƒç©ºç™½å—符模 msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "é…ç½®å˜é‡ 'diff.submodule' 未知的å–值:'%s'" +#: diff.c transport.c +#, c-format +msgid "unknown value for config '%s': %s" +msgstr "é…ç½® '%s' 未知的å–值:%s" + #: diff.c #, c-format msgid "" @@ -19261,13 +19498,6 @@ msgid "invalid mode '%s' in --color-moved-ws" msgstr "--color-moved-ws ä¸çš„æ— æ•ˆæ¨¡å¼ '%s' " #: diff.c -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"diff-algorithm 选项有 \"myers\"ã€\"minimal\"ã€\"patience\" å’Œ \"histogram\"" - -#: diff.c #, c-format msgid "invalid argument to %s" msgstr "%s çš„å‚æ•°æ— 效" @@ -19324,8 +19554,8 @@ msgid "output only the last line of --stat" msgstr "åªè¾“出 --stat 的最åŽä¸€è¡Œ" #: diff.c -msgid "<param1,param2>..." -msgstr "<傿•°1,傿•°2>..." +msgid "<param1>,<param2>..." +msgstr "<傿•°1>,<傿•°2>..." #: diff.c msgid "" @@ -19337,8 +19567,8 @@ msgid "synonym for --dirstat=cumulative" msgstr "å’Œ --dirstat=cumulative åŒä¹‰" #: diff.c -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "是 --dirstat=files,param1,param2... çš„åŒä¹‰è¯" +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "是 --dirstat=files,<傿•°1>,<傿•°2>... çš„åŒä¹‰è¯" #: diff.c msgid "warn if changes introduce conflict markers or whitespace errors" @@ -19561,14 +19791,6 @@ msgid "generate diff using the \"histogram diff\" algorithm" msgstr "使用 \"histogram diff\" 算法生æˆå·®å¼‚" #: diff.c -msgid "<algorithm>" -msgstr "<算法>" - -#: diff.c -msgid "choose a diff algorithm" -msgstr "选择一个差异算法" - -#: diff.c msgid "<text>" msgstr "<文本>" @@ -20820,12 +21042,12 @@ msgstr "" "%s" #: merge-ort.c merge-recursive.c -msgid "Failed to execute internal merge" +msgid "failed to execute internal merge" msgstr "æ— æ³•æ‰§è¡Œå†…éƒ¨åˆå¹¶" #: merge-ort.c merge-recursive.c #, c-format -msgid "Unable to add %s to database" +msgid "unable to add %s to database" msgstr "ä¸èƒ½æ·»åŠ %s 至对象库" #: merge-ort.c merge-recursive.c @@ -21321,7 +21543,21 @@ msgstr "æ— æ³•è¯»å–缓å˜" #: midx.c msgid "multi-pack-index OID fanout is of the wrong size" -msgstr "多包索引的对象ID扇出表大å°é”™è¯¯" +msgstr "多包索引的对象 ID 扇出表大å°é”™è¯¯" + +#: midx.c +#, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "对象 ID 扇出失åºï¼šfanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" + +#: midx.c +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "多包索引的对象 ID 查询å—大å°é”™è¯¯" + +#: midx.c +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "多包索引的对象 ID åç§»å—大å°é”™è¯¯" #: midx.c #, c-format @@ -21344,20 +21580,24 @@ msgid "multi-pack-index hash version %u does not match version %u" msgstr "多包索引哈希版本 %u 和版本 %u ä¸åŒ¹é…" #: midx.c -msgid "multi-pack-index missing required pack-name chunk" -msgstr "多包索引缺少必需的包åå—" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "多包索引必需的包åå—缺失或æŸå" + +#: midx.c +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "多包索引必需的对象 ID 扇出å—缺失或æŸå" #: midx.c -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "多包索引缺少必需的对象 ID 扇出å—" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "多包索引必需的对象 ID 查询å—缺失或æŸå" #: midx.c -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "多包索引缺少必需的对象 ID 查询å—" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "多包索引必需的对象åç§»å—缺少或æŸå" #: midx.c -msgid "multi-pack-index missing required object offsets chunk" -msgstr "多包索引缺少必需的对象åç§»å—" +msgid "multi-pack-index pack-name chunk is too short" +msgstr "多包索引包åå—过çŸ" #: midx.c #, c-format @@ -21370,10 +21610,23 @@ msgid "bad pack-int-id: %u (%u total packs)" msgstr "错的 pack-int-id:%u(共有 %u 个包)" #: midx.c +msgid "MIDX does not contain the BTMP chunk" +msgstr "å¤šåŒ…ç´¢å¼•ä¸æœªåŒ…å« BTMP å—" + +#: midx.c +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "ä¸èƒ½æ‰“开已被ä½å›¾ç´¢å¼•的包 %<PRIu32>" + +#: midx.c msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "多包索引å˜å‚¨ä¸€ä¸ª64ä½å移,但是 off_t 太å°" #: midx.c +msgid "multi-pack-index large offset out of bounds" +msgstr "多包索引大å移区越界" + +#: midx.c #, c-format msgid "failed to add packfile '%s'" msgstr "æ— æ³•æ·»åŠ åŒ…æ–‡ä»¶ '%s'" @@ -21473,12 +21726,6 @@ msgid "Looking for referenced packfiles" msgstr "æ£åœ¨æŸ¥æ‰¾å¼•用的包文件" #: midx.c -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "对象 ID æ‰‡å‡ºæ— åºï¼šfanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" - -#: midx.c msgid "the midx contains no oid" msgstr "midx ä¸åŒ…å« oid" @@ -22107,6 +22354,10 @@ msgstr "多包ä½å›¾ç¼ºå°‘必需的åå‘索引" msgid "could not open pack %s" msgstr "ä¸èƒ½æ‰“开包 %s" +#: pack-bitmap.c t/helper/test-read-midx.c +msgid "could not determine MIDX preferred pack" +msgstr "ä¸èƒ½ç¡®å®šå¤šåŒ…索引的首选包" + #: pack-bitmap.c #, c-format msgid "preferred pack (%s) is invalid" @@ -22132,6 +22383,11 @@ msgstr "æŸåçš„ EWAH ä½å›¾ï¼šæäº¤ \"%s\" ä½å›¾çš„æ–‡ä»¶å¤´è¢«æˆªæ–" #: pack-bitmap.c #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "æ— æ³•æ‰“å¼€åŒ…ï¼š'%s',ç¦ç”¨åŒ…é‡ç”¨" + +#: pack-bitmap.c +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "对象 %s 为在类型ä½å›¾ä¸æ‰¾åˆ°" @@ -22241,6 +22497,14 @@ msgstr "æ— æ•ˆçš„æ ¡éªŒç %s" msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "ä½äºŽ %<PRIu64> çš„æ— æ•ˆçš„åå‘索引:%<PRIu32> != %<PRIu32>" +#: pack-revindex.c +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "多包索引的åå‘索引å—大å°é”™è¯¯" + +#: pack-revindex.c +msgid "could not determine preferred pack" +msgstr "æ— æ³•ç¡®å®šé¦–é€‰åŒ…" + #: pack-write.c msgid "cannot both write and verify reverse index" msgstr "æ— æ³•åŒæ—¶å†™å…¥å’Œæ ¡éªŒåå‘索引" @@ -22306,16 +22570,6 @@ msgstr "%s 需è¦ä¸€ä¸ªå€¼" #: parse-options.c #, c-format -msgid "%s is incompatible with %s" -msgstr "%s 与 %s ä¸å…¼å®¹" - -#: parse-options.c -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s:和其它的ä¸å…¼å®¹" - -#: parse-options.c -#, c-format msgid "%s takes no value" msgstr "%s ä¸å–值" @@ -22414,6 +22668,11 @@ msgstr " %s" msgid "-NUM" msgstr "-æ•°å—" +#: parse-options.c +#, c-format +msgid "opposite of --no-%s" +msgstr "与 --no-%s 相å" + #: parse-options.h msgid "expiry-date" msgstr "到期时间" @@ -22451,6 +22710,16 @@ msgid "" "with --pathspec-from-file, pathspec elements are separated with NUL character" msgstr "使用 --pathspec-from-file,路径表达å¼ç”¨ç©ºå—符分隔" +#: parse.c +#, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "对于 '%2$s' 的错误的布尔环境å–值 '%1$s'" + +#: parse.c +#, c-format +msgid "failed to parse %s" +msgstr "æ— æ³•è§£æž %s" + #: path.c #, c-format msgid "Could not make %s writable by group" @@ -22509,6 +22778,11 @@ msgstr "%s:'literal' å’Œ 'glob' ä¸å…¼å®¹" #: pathspec.c #, c-format +msgid "'%s' is outside the directory tree" +msgstr "'%s' ä½äºŽç›®å½•æ ‘ä¹‹å¤–" + +#: pathspec.c +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s:'%s' 在ä½äºŽ '%s' 的仓库之外" @@ -22700,11 +22974,6 @@ msgstr "æ— æ³•åœ¨ç´¢å¼•ä¸æ·»åŠ '%s'" #: read-cache.c #, c-format -msgid "unable to stat '%s'" -msgstr "æ— æ³•å¯¹ %s 执行 stat" - -#: read-cache.c -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "'%s' çœ‹èµ·æ¥æ—¢æ˜¯æ–‡ä»¶åˆæ˜¯ç›®å½•" @@ -22838,11 +23107,6 @@ msgstr "æ— æ³•è½¬æ¢ä¸ºç¨€ç–索引" #: read-cache.c #, c-format -msgid "could not stat '%s'" -msgstr "ä¸èƒ½å¯¹ '%s' 调用 stat" - -#: read-cache.c -#, c-format msgid "unable to open git dir: %s" msgstr "ä¸èƒ½æ‰“å¼€ git 目录:%s" @@ -23382,17 +23646,12 @@ msgstr "'%s' å·²å˜åœ¨ï¼Œæ— 法创建 '%s'" msgid "cannot process '%s' and '%s' at the same time" msgstr "æ— æ³•åŒæ—¶å¤„ç† '%s' å’Œ '%s'" -#: refs/files-backend.c -#, c-format -msgid "could not remove reference %s" -msgstr "æ— æ³•åˆ é™¤å¼•ç”¨ %s" - -#: refs/files-backend.c refs/packed-backend.c +#: refs.c #, c-format msgid "could not delete reference %s: %s" msgstr "æ— æ³•åˆ é™¤å¼•ç”¨ %s:%s" -#: refs/files-backend.c refs/packed-backend.c +#: refs.c #, c-format msgid "could not delete references: %s" msgstr "æ— æ³•åˆ é™¤å¼•ç”¨ï¼š%s" @@ -24067,8 +24326,16 @@ msgid "only download metadata for the branch that will be checked out" msgstr "åªä¸‹è½½è¦æ£€å‡ºçš„分支的元信æ¯" #: scalar.c -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [<选项>] [--] <仓库> [<目录>]" +msgid "create repository within 'src' directory" +msgstr "在 'src' 目录ä¸åˆ›å»ºä»“库" + +#: scalar.c +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<登记>]" #: scalar.c #, c-format @@ -24134,13 +24401,32 @@ msgstr "æ— æ³•åˆ é™¤è¿‡æœŸçš„ scalar.repo '%s'" #: scalar.c #, c-format -msgid "removing stale scalar.repo '%s'" -msgstr "æ£åœ¨åˆ 除过期的 scalar.repo '%s'" +msgid "removed stale scalar.repo '%s'" +msgstr "å·²åˆ é™¤è¿‡æœŸçš„ scalar.repo '%s'" + +#: scalar.c +#, c-format +msgid "repository at '%s' has different owner" +msgstr "ä½äºŽ '%s' 处的仓库有ä¸åŒçš„æ‰€æœ‰è€…" #: scalar.c #, c-format -msgid "git repository gone in '%s'" -msgstr "在 '%s' çš„ git 仓库已消失" +msgid "repository at '%s' has a format issue" +msgstr "ä½äºŽ '%s' 处的仓库å˜åœ¨æ ¼å¼é—®é¢˜" + +#: scalar.c +#, c-format +msgid "repository not found in '%s'" +msgstr "在 '%s' 䏿‰¾ä¸åˆ°ä»“库" + +#: scalar.c +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"若希望从 Scalar 注销该仓库,执行\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" #: scalar.c msgid "" @@ -24520,7 +24806,7 @@ msgstr "æ— æ•ˆçš„ä½œè€…èº«ä»½ '%s'" msgid "corrupt author: missing date information" msgstr "æŸå的作者:缺失日期信æ¯" -#: sequencer.c t/helper/test-fast-rebase.c +#: sequencer.c #, c-format msgid "could not update %s" msgstr "ä¸èƒ½æ›´æ–° %s" @@ -24617,11 +24903,6 @@ msgstr "%s:ä¸èƒ½è§£æžçˆ¶æäº¤ %s" #: sequencer.c #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "ä¸èƒ½å°† '%s' é‡å‘½å为 '%s'" - -#: sequencer.c -#, c-format msgid "could not revert %s... %s" msgstr "ä¸èƒ½è¿˜åŽŸ %s... %s" @@ -25016,6 +25297,10 @@ msgid "Autostash exists; creating a new stash entry." msgstr "自动贮è—å·²ç»å˜åœ¨ï¼›æ£åœ¨åˆ›å»ºä¸€ä¸ªæ–°çš„è´®è—æ¡ç›®ã€‚" #: sequencer.c +msgid "autostash reference is a symref" +msgstr "自动贮è—的引用是一个符å·å¼•用" + +#: sequencer.c msgid "could not detach HEAD" msgstr "ä¸èƒ½åˆ†ç¦»å¤´æŒ‡é’ˆ" @@ -25051,13 +25336,13 @@ msgstr "" #: sequencer.c #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "æ£åœ¨å˜åŸºï¼ˆ%d/%d)%s" +msgid "Stopped at %s... %.*s\n" +msgstr "åœæ¢åœ¨ %s... %.*s\n" #: sequencer.c #, c-format -msgid "Stopped at %s... %.*s\n" -msgstr "åœæ¢åœ¨ %s... %.*s\n" +msgid "Rebasing (%d/%d)%s" +msgstr "æ£åœ¨å˜åŸºï¼ˆ%d/%d)%s" #: sequencer.c #, c-format @@ -25391,6 +25676,11 @@ msgstr "æ— æ•ˆçš„åˆå§‹åˆ†æ”¯å:'%s'" #: setup.c #, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "re-init:已忽略 --initial-branch=%s" + +#: setup.c +#, c-format msgid "unable to handle file type %d" msgstr "ä¸èƒ½å¤„ç† %d 类型的文件" @@ -25404,14 +25694,14 @@ msgid "attempt to reinitialize repository with different hash" msgstr "å°è¯•用ä¸åŒçš„å“ˆå¸Œç®—æ³•é‡æ–°åˆå§‹åŒ–仓库" #: setup.c -#, c-format -msgid "%s already exists" -msgstr "%s å·²ç»å˜åœ¨" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "å°è¯•使用ä¸åŒçš„引用å˜å‚¨æ ¼å¼é‡æ–°åˆå§‹åŒ–仓库" #: setup.c #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "re-init:已忽略 --initial-branch=%s" +msgid "%s already exists" +msgstr "%s å·²ç»å˜åœ¨" #: setup.c #, c-format @@ -25729,14 +26019,6 @@ msgstr "åœ¨æ¯æ¬¡è¿ä»£å‰æ¸…é™¤ç¼“å˜æ ‘" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "ç¼“å˜æ ‘䏿— 效化的æ¡ç›®æ•°é‡ï¼ˆé»˜è®¤ 0)" -#: t/helper/test-fast-rebase.c -msgid "unhandled options" -msgstr "未处ç†çš„选项" - -#: t/helper/test-fast-rebase.c -msgid "error preparing revisions" -msgstr "准备版本时错误" - #: t/helper/test-reach.c #, c-format msgid "commit %s is not marked reachable" @@ -25930,10 +26212,6 @@ msgstr "åè®®ä¸æ”¯æŒè®¾ç½®è¿œç¨‹æœåŠ¡è·¯å¾„" msgid "invalid remote service path" msgstr "æ— æ•ˆçš„è¿œç¨‹æœåŠ¡è·¯å¾„" -#: transport-helper.c transport.c -msgid "operation not supported by protocol" -msgstr "åè®®ä¸æ”¯æŒè¯¥æ“作" - #: transport-helper.c #, c-format msgid "can't connect to subservice %s" @@ -26099,11 +26377,6 @@ msgstr "åè®® v2 的支æŒå°šæœªå®žçް" #: transport.c #, c-format -msgid "unknown value for config '%s': %s" -msgstr "é…ç½® '%s' çš„å–值未知:%s" - -#: transport.c -#, c-format msgid "transport '%s' not allowed" msgstr "ä¼ è¾“ '%s' ä¸å…许" @@ -26161,6 +26434,10 @@ msgstr "åè®®ä¸æ”¯æŒ bundle-uri æ“作" msgid "could not retrieve server-advertised bundle-uri list" msgstr "æ— æ³•èŽ·å–æœåŠ¡å™¨å…¬å¸ƒçš„ bundle-uri 列表" +#: transport.c +msgid "operation not supported by protocol" +msgstr "åè®®ä¸æ”¯æŒè¯¥æ“作" + #: tree-walk.c msgid "too-short tree object" msgstr "太çŸçš„æ ‘对象" @@ -26613,6 +26890,10 @@ msgstr "ä¸èƒ½è®¿é—® '%s'" msgid "unable to get current working directory" msgstr "ä¸èƒ½èŽ·å–当å‰å·¥ä½œç›®å½•" +#: wrapper.c +msgid "unable to get random bytes" +msgstr "æ— æ³•èŽ·å–éšæœºå—节" + #: wt-status.c msgid "Unmerged paths:" msgstr "未åˆå¹¶çš„路径:" @@ -27185,6 +27466,11 @@ msgstr "å¦å¤–,您的索引ä¸åŒ…嫿œªæäº¤çš„å˜æ›´ã€‚" msgid "cannot %s: Your index contains uncommitted changes." msgstr "ä¸èƒ½%s:您的索引ä¸åŒ…嫿œªæäº¤çš„å˜æ›´ã€‚" +#: xdiff-interface.c +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "'%2$s' çš„æœªçŸ¥é£Žæ ¼å–值 '%1$s'" + #: git-merge-octopus.sh git-merge-resolve.sh msgid "" "Error: Your local changes to the following files would be overwritten by " @@ -27401,13 +27687,13 @@ msgstr "" #: git-send-email.perl #, perl-format -msgid "Failed to open %s: %s" -msgstr "æ— æ³•æ‰“å¼€ %s: %s" +msgid "Failed to open %s.final: %s" +msgstr "æ— æ³•æ‰“å¼€ %s.final: %s" #: git-send-email.perl #, perl-format -msgid "Failed to open %s.final: %s" -msgstr "æ— æ³•æ‰“å¼€ %s.final: %s" +msgid "Failed to open %s: %s" +msgstr "æ— æ³•æ‰“å¼€ %s: %s" #: git-send-email.perl msgid "Summary email is empty, skipping it\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index 6ae75e7e19..312dd128a4 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -1,7 +1,7 @@ # Chinese (traditional) translations for Git package # Git 套è£è»Ÿé«”çš„ç¹é«”䏿–‡ç¿»è¯ã€‚ # Copyright (C) 2012-2021 Jiang Xin <worldhello.net AT gmail.com> -# Copyright (C) 2019-2022 Yi-Jyun Pan <pan93412@gmail.com> +# Copyright (C) 2019-2023 Yi-Jyun Pan <pan93412@gmail.com> # This file is distributed under the same license as the Git package. # # The glossary can be found on https://github.com/l10n-tw/git-glossary @@ -19,15 +19,15 @@ # - Yichao Yu <yyc1992 AT gmail.com> # - Zhuang Ya <zhuangya AT me.com> # -# Yi-Jyun Pan <pan93412@gmail.com>, 2021, 2022, 2023. +# Yi-Jyun Pan <pan93412@gmail.com>, 2021, 2022, 2023, 2024. # Kaiyang Wu <self@origincode.me>, 2022. -# lumynou5 <lumynou5.tw@gmail.com>, 2023. +# lumynou5 <lumynou5.tw@gmail.com>, 2023, 2024. msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-08-20 21:51+0800\n" -"PO-Revision-Date: 2023-08-20 21:58+0800\n" +"POT-Creation-Date: 2024-02-18 20:48+0800\n" +"PO-Revision-Date: 2024-02-18 20:50+0800\n" "Last-Translator: Yi-Jyun Pan <pan93412@gmail.com>\n" "Language-Team: Chinese (Traditional) <http://weblate.slat.org/projects/git-" "po/git-cli/zh_Hant/>\n" @@ -36,7 +36,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.3.2\n" +"X-Generator: Poedit 3.4.2\n" "X-ZhConverter: ç¹åŒ–姬 dict-f4bc617e-r910 @ 2019/11/16 20:23:12 | https://" "zhconvert.org\n" @@ -910,7 +910,7 @@ msgid "unclosed quote" msgstr "未閉åˆçš„引號" #: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c -#: builtin/receive-pack.c builtin/tag.c +#: builtin/receive-pack.c builtin/tag.c t/helper/test-pkt-line.c msgid "too many arguments" msgstr "引數éŽå¤š" @@ -924,14 +924,16 @@ msgstr "空白å—å…ƒé¸é … “%s†無法è˜åˆ¥" msgid "unrecognized whitespace ignore option '%s'" msgstr "空白å—元忽略é¸é … “%s†無法è˜åˆ¥" -#: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout.c -#: builtin/clone.c builtin/commit.c builtin/describe.c builtin/diff-tree.c -#: builtin/difftool.c builtin/fast-export.c builtin/fetch.c builtin/help.c -#: builtin/index-pack.c builtin/init-db.c builtin/log.c builtin/ls-files.c -#: builtin/merge-base.c builtin/merge.c builtin/pack-objects.c builtin/push.c -#: builtin/rebase.c builtin/repack.c builtin/reset.c builtin/rev-list.c -#: builtin/show-branch.c builtin/stash.c builtin/submodule--helper.c -#: builtin/tag.c builtin/worktree.c parse-options.c range-diff.c revision.c +#: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c +#: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c +#: builtin/describe.c builtin/diff-tree.c builtin/difftool.c +#: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c +#: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c +#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c +#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-list.c +#: builtin/rev-parse.c builtin/show-branch.c builtin/stash.c +#: builtin/submodule--helper.c builtin/tag.c builtin/worktree.c parse-options.c +#: range-diff.c revision.c #, c-format msgid "options '%s' and '%s' cannot be used together" msgstr "ç„¡æ³•åŒæ™‚使用 “%s†和 “%s†é¸é …" @@ -1239,12 +1241,12 @@ msgstr "%s:已å˜åœ¨æ–¼å·¥ä½œå€ä¸" #: apply.c #, c-format msgid "new mode (%o) of %s does not match old mode (%o)" -msgstr "%2$s çš„æ–°æ¨¡å¼ (%1$o) å’ŒèˆŠæ¨¡å¼ (%3$o) ä¸ç¬¦" +msgstr "%2$s 的新模å¼ï¼ˆ%1$o)和舊模å¼ï¼ˆ%3$o)ä¸ç¬¦" #: apply.c #, c-format msgid "new mode (%o) of %s does not match old mode (%o) of %s" -msgstr "%2$s çš„æ–°æ¨¡å¼ (%1$o) å’Œ %4$s çš„èˆŠæ¨¡å¼ (%3$o) ä¸ç¬¦" +msgstr "%2$s 的新模å¼ï¼ˆ%1$o)和 %4$s 的舊模å¼ï¼ˆ%3$o)ä¸ç¬¦" #: apply.c #, c-format @@ -1402,7 +1404,7 @@ msgid "%d line applied after fixing whitespace errors." msgid_plural "%d lines applied after fixing whitespace errors." msgstr[0] "ä¿®æ£ç©ºç™½èª¤ç”¨å¾Œï¼Œå¥—用了 %d 列。" -#: apply.c builtin/add.c builtin/mv.c builtin/rm.c +#: apply.c builtin/mv.c builtin/rm.c msgid "Unable to write new index file" msgstr "無法寫入新索引檔案" @@ -1733,6 +1735,11 @@ msgstr "éžé 期é¸é … --output" #: archive.c #, c-format +msgid "extra command line parameter '%s'" +msgstr "å¤šå‡ºå‘½ä»¤åˆ—åƒæ•¸ “%sâ€" + +#: archive.c +#, c-format msgid "Unknown archive format '%s'" msgstr "å°å˜æ ¼å¼ “%s†未知" @@ -1787,6 +1794,17 @@ msgstr "忽略éŽå¤§çš„ gitattributes 資料物件 “%sâ€" msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "無效的 --attr-source 或 GIT_ATTR_SOURCE" +#: attr.c read-cache.c +#, c-format +msgid "unable to stat '%s'" +msgstr "ç„¡æ³•å° %s 執行 stat" + +#: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c +#: builtin/pack-objects.c combine-diff.c rerere.c +#, c-format +msgid "unable to read %s" +msgstr "ä¸èƒ½è®€ %s" + #: bisect.c #, c-format msgid "Badly quoted content in file '%s': %s" @@ -2106,8 +2124,8 @@ msgstr "“%sâ€ åæ¨¡çµ„:無法建立 “%s†分支" #: branch.c #, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "“%s†已在 “%s†點簽出" +msgid "'%s' is already used by worktree at '%s'" +msgstr "“%sâ€ å·²è¢«ä½æ–¼ “%s†的工作å€ä½¿ç”¨" #: builtin/add.c msgid "git add [<options>] [--] <pathspec>..." @@ -2130,30 +2148,26 @@ msgstr "" "add.interactive.useBuiltin è¨å®šå·²è¢«ç§»é™¤ï¼\n" "深入了解請åƒé–± “git help config†ä¸çš„å°æ‡‰æ¢ç›®ã€‚" -#: builtin/add.c builtin/rev-parse.c -msgid "Could not read the index" -msgstr "無法讀å–索引" - #: builtin/add.c -msgid "Could not write patch" -msgstr "無法寫入修補檔" +msgid "could not read the index" +msgstr "無法讀å–索引" #: builtin/add.c msgid "editing patch failed" msgstr "編輯修補檔失敗" -#: builtin/add.c +#: builtin/add.c read-cache.c #, c-format -msgid "Could not stat '%s'" -msgstr "ä¸èƒ½å° “%s†執行 stat" +msgid "could not stat '%s'" +msgstr "ä¸èƒ½å° '%s' å‘¼å« stat" #: builtin/add.c -msgid "Empty patch. Aborted." -msgstr "ä¿®è£œæª”ç©ºç™½ã€‚ä¸æ¢ã€‚" +msgid "empty patch. aborted" +msgstr "ä¿®è£œæª”ç©ºç™½ã€‚ä¸æ¢" #: builtin/add.c #, c-format -msgid "Could not apply '%s'" +msgid "could not apply '%s'" msgstr "無法套用 “%sâ€" #: builtin/add.c @@ -2315,14 +2329,19 @@ msgstr "" msgid "index file corrupt" msgstr "索引檔案æå£ž" +#: builtin/add.c builtin/am.c builtin/checkout.c builtin/clone.c +#: builtin/commit.c builtin/stash.c merge.c rerere.c +msgid "unable to write new index file" +msgstr "無法寫入新的索引檔案" + #: builtin/am.c builtin/mailinfo.c mailinfo.c #, c-format msgid "bad action '%s' for '%s'" msgstr "“%sâ€ å‹•ä½œå° â€œ%s†無效" #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c -#: builtin/pull.c diff-merges.c gpg-interface.c ls-refs.c parallel-checkout.c -#: sequencer.c setup.c +#: builtin/pull.c config.c diff-merges.c gpg-interface.c ls-refs.c +#: parallel-checkout.c sequencer.c setup.c #, c-format msgid "invalid value for '%s': '%s'" msgstr "“%s†的值無效:“%sâ€" @@ -2475,8 +2494,7 @@ msgstr "git write-tree 無法寫入樹狀物件" msgid "applying to an empty history" msgstr "æ£åœ¨å¥—用至空白æ·å²è¨˜éŒ„上" -#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c -#: t/helper/test-fast-rebase.c +#: builtin/am.c builtin/commit.c builtin/merge.c builtin/replay.c sequencer.c msgid "failed to write commit object" msgstr "無法寫入æäº¤ç‰©ä»¶" @@ -2565,11 +2583,6 @@ msgstr "" "您應該å°å·²ç¶“解決è¡çªçš„æ¯ä¸€å€‹æª”æ¡ˆåŸ·è¡Œ `git add`,標記為已經完æˆã€‚\n" "ä½ å¯ä»¥å°ã€Œç”±ä»–們刪除ã€çš„æª”案,執行 `git rm` 指令。" -#: builtin/am.c builtin/checkout.c builtin/clone.c builtin/stash.c merge.c -#: rerere.c -msgid "unable to write new index file" -msgstr "無法寫入新的索引檔案" - #: builtin/am.c builtin/reset.c #, c-format msgid "Could not parse object '%s'." @@ -2593,11 +2606,6 @@ msgid "failed to read '%s'" msgstr "ç„¡æ³•è®€å– â€œ%sâ€" #: builtin/am.c -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "“%s=%s†和 “%s=%s†é¸é …ä¸å¾—åŒæ™‚使用" - -#: builtin/am.c msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<options>] [(<mbox> | <Maildir>)...]" @@ -2669,8 +2677,9 @@ msgid "n" msgstr "n" #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c -#: builtin/diagnose.c builtin/for-each-ref.c builtin/ls-files.c -#: builtin/ls-tree.c builtin/replace.c builtin/tag.c builtin/verify-tag.c +#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c +#: builtin/ls-files.c builtin/ls-tree.c builtin/replace.c builtin/tag.c +#: builtin/verify-tag.c msgid "format" msgstr "format" @@ -2800,10 +2809,10 @@ msgstr "git archiveï¼šé æœŸæ”¶åˆ° flush å°åŒ…" #: builtin/bisect.c msgid "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" msgstr "" -"git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] [--no-" +"git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" #: builtin/bisect.c @@ -2823,8 +2832,8 @@ msgid "git bisect replay <logfile>" msgstr "git bisect replay <logfile>" #: builtin/bisect.c -msgid "git bisect run <cmd>..." -msgstr "git bisect run <cmd>..." +msgid "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <cmd> [<arg>...]" #: builtin/bisect.c #, c-format @@ -3343,37 +3352,38 @@ msgstr "git branch [<options>] [-r | -a] [--format]" #, c-format msgid "" "deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." +" '%s', but not yet merged to HEAD" msgstr "" "å°‡è¦åˆªé™¤çš„ “%s†分支已經被åˆä½µåˆ°\n" -" “%sâ€ï¼Œä½†å°šæœªåˆä½µåˆ° HEAD。" +" “%sâ€ï¼Œä½†å°šæœªåˆä½µåˆ° HEAD" # è¯è€…ï¼šä¿æŒåŽŸæ›è¡Œæ ¼å¼ï¼Œåœ¨è¼¸å‡ºæ™‚ %s 的替代內容會讓å—串變長 #: builtin/branch.c #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." +" '%s', even though it is merged to HEAD" msgstr "" "並未刪除分支 “%sâ€ï¼Œ 雖然已經åˆä½µåˆ° HEAD,\n" -" å»å°šæœªè¢«åˆä½µè‡³ “%s†分支。" +" å»å°šæœªè¢«åˆä½µè‡³ “%s†分支" #: builtin/branch.c #, c-format -msgid "Couldn't look up commit object for '%s'" +msgid "couldn't look up commit object for '%s'" msgstr "無法查詢 “%s†指å‘çš„æäº¤ç‰©ä»¶" #: builtin/branch.c #, 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 "" -"分支 “%s†沒有完全åˆä½µã€‚\n" -"如果確定è¦åˆªé™¤å®ƒï¼Œè«‹åŸ·è¡Œ “git branch -D %sâ€ã€‚" +msgid "the branch '%s' is not fully merged" +msgstr "分支 “%s†沒有完全åˆä½µ" + +#: builtin/branch.c +#, c-format +msgid "If you are sure you want to delete it, run 'git branch -D %s'" +msgstr "如果確定è¦åˆªé™¤å®ƒï¼Œè«‹åŸ·è¡Œ “git branch -D %sâ€" #: builtin/branch.c -msgid "Update of config-file failed" +msgid "update of config-file failed" msgstr "更新組態檔案失敗" #: builtin/branch.c @@ -3382,13 +3392,13 @@ msgstr "ä¸èƒ½å°‡ -a å’Œ -d åŒæ™‚使用" #: builtin/branch.c #, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "無法刪除在 “%2$s†簽出的 “%1$s†分支" +msgid "cannot delete branch '%s' used by worktree at '%s'" +msgstr "ç„¡æ³•åˆªé™¤è¢«ä½æ–¼ “%2$s†的工作å€ä½¿ç”¨çš„ “%1$s†分支" #: builtin/branch.c #, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "找ä¸åˆ° “%s†é 端追蹤分支。" +msgid "remote-tracking branch '%s' not found" +msgstr "找ä¸åˆ° “%s†é 端追蹤分支" #: builtin/branch.c #, c-format @@ -3401,8 +3411,8 @@ msgstr "" #: builtin/branch.c #, c-format -msgid "branch '%s' not found." -msgstr "找ä¸åˆ° “%s†分支。" +msgid "branch '%s' not found" +msgstr "找ä¸åˆ° “%s†分支" #: builtin/branch.c #, c-format @@ -3429,12 +3439,12 @@ msgstr "HEAD æŒ‡é‡ (%s) æŒ‡å‘ refs/heads/ 之外" #: builtin/branch.c #, c-format -msgid "Branch %s is being rebased at %s" +msgid "branch %s is being rebased at %s" msgstr "%s 分支æ£åœ¨é‡å®šåŸºåº•至 %s" #: builtin/branch.c #, c-format -msgid "Branch %s is being bisected at %s" +msgid "branch %s is being bisected at %s" msgstr "%s åˆ†æ”¯æ£æ–¼ %s 進行二分æœå°‹" #: builtin/branch.c @@ -3444,48 +3454,48 @@ msgstr "%s 工作å€çš„ HEAD æŒ‡é‡æœªè¢«æ›´æ–°" #: builtin/branch.c #, c-format -msgid "Invalid branch name: '%s'" +msgid "invalid branch name: '%s'" msgstr "分支å稱無效:“%sâ€" #: builtin/branch.c #, c-format -msgid "No commit on branch '%s' yet." -msgstr "分支 “%s†尚無æäº¤ã€‚" +msgid "no commit on branch '%s' yet" +msgstr "分支 “%s†尚無æäº¤" #: builtin/branch.c #, c-format -msgid "No branch named '%s'." -msgstr "沒有å為 “%s†的分支。" +msgid "no branch named '%s'" +msgstr "沒有å為 “%s†的分支" #: builtin/branch.c -msgid "Branch rename failed" +msgid "branch rename failed" msgstr "åˆ†æ”¯é‡æ–°å‘½å失敗" #: builtin/branch.c -msgid "Branch copy failed" +msgid "branch copy failed" msgstr "分支拷è²å¤±æ•—" #: builtin/branch.c #, c-format -msgid "Created a copy of a misnamed branch '%s'" +msgid "created a copy of a misnamed branch '%s'" msgstr "已為誤命åçš„ “%s†分支建立拷è²" #: builtin/branch.c #, c-format -msgid "Renamed a misnamed branch '%s' away" +msgid "renamed a misnamed branch '%s' away" msgstr "已更改誤命åçš„ “%s†分支的å稱" #: builtin/branch.c #, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "åˆ†æ”¯å·²é‡æ–°å‘½å為 %s,但 HEAD 指é‡å°šæœªæ›´æ–°ï¼" +msgid "branch renamed to %s, but HEAD is not updated" +msgstr "åˆ†æ”¯å·²é‡æ–°å‘½å為 %s,但 HEAD 指é‡å°šæœªæ›´æ–°" #: builtin/branch.c -msgid "Branch is renamed, but update of config-file failed" +msgid "branch is renamed, but update of config-file failed" msgstr "åˆ†æ”¯å·²é‡æ–°å‘½å,但無法更新組態檔案" #: builtin/branch.c -msgid "Branch is copied, but update of config-file failed" +msgid "branch is copied, but update of config-file failed" msgstr "分支已拷è²ï¼Œä½†ç„¡æ³•更新組態檔案" #: builtin/branch.c @@ -3636,9 +3646,9 @@ msgstr "åœ¨åæ¨¡çµ„ä¸éžè¿´" msgid "format to use for the output" msgstr "è¼¸å‡ºæ ¼å¼" -#: builtin/branch.c builtin/submodule--helper.c submodule.c -msgid "Failed to resolve HEAD as a valid ref." -msgstr "無法將 HEAD è§£æžç‚ºæœ‰æ•ˆå¼•用。" +#: builtin/branch.c +msgid "failed to resolve HEAD as a valid ref" +msgstr "無法將 HEAD è§£æžç‚ºæœ‰æ•ˆå¼•用" #: builtin/branch.c builtin/clone.c msgid "HEAD not found below refs/heads!" @@ -3660,7 +3670,7 @@ msgid "branch name required" msgstr "å¿…é ˆæä¾›åˆ†æ”¯å稱" #: builtin/branch.c -msgid "Cannot give description to detached HEAD" +msgid "cannot give description to detached HEAD" msgstr "無法å‘分離 HEAD æŒ‡é‡æä¾›æè¿°" #: builtin/branch.c @@ -3668,12 +3678,12 @@ msgid "cannot edit description of more than one branch" msgstr "無法編輯超éŽä¸€å€‹åˆ†æ”¯çš„æè¿°" #: builtin/branch.c -msgid "cannot copy the current branch while not on any." -msgstr "ä¸åœ¨ä»»ä½•分支上,無法拷è²ç›®å‰åˆ†æ”¯ã€‚" +msgid "cannot copy the current branch while not on any" +msgstr "ä¸åœ¨ä»»ä½•分支上,無法拷è²ç›®å‰åˆ†æ”¯" #: builtin/branch.c -msgid "cannot rename the current branch while not on any." -msgstr "ä¸åœ¨ä»»ä½•åˆ†æ”¯ä¸Šï¼Œç„¡æ³•é‡æ–°å‘½åç›®å‰åˆ†æ”¯ã€‚" +msgid "cannot rename the current branch while not on any" +msgstr "ä¸åœ¨ä»»ä½•åˆ†æ”¯ä¸Šï¼Œç„¡æ³•é‡æ–°å‘½åç›®å‰åˆ†æ”¯" #: builtin/branch.c msgid "too many branches for a copy operation" @@ -3690,8 +3700,8 @@ msgstr "è¦è¨å®šæ–°ä¸Šæ¸¸çš„引數太多" #: builtin/branch.c #, c-format msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." -msgstr "無法將 HEAD 的上游è¨ç‚º %s:其未指å‘任何分支。" +"could not set upstream of HEAD to %s when it does not point to any branch" +msgstr "無法將 HEAD 的上游è¨ç‚º %s:其未指å‘任何分支" #: builtin/branch.c #, c-format @@ -3708,17 +3718,17 @@ msgid "too many arguments to unset upstream" msgstr "è¦å–消è¨å®šä¸Šæ¸¸çš„引數太多" #: builtin/branch.c -msgid "could not unset upstream of HEAD when it does not point to any branch." -msgstr "ç„¡æ³•å–æ¶ˆè¨å®š HEAD 的上游:其未指å‘任何分支。" +msgid "could not unset upstream of HEAD when it does not point to any branch" +msgstr "ç„¡æ³•å–æ¶ˆè¨å®š HEAD 的上游:其未指å‘任何分支" #: builtin/branch.c #, c-format -msgid "Branch '%s' has no upstream information" +msgid "branch '%s' has no upstream information" msgstr "分支 “%s†沒有上游資訊" #: builtin/branch.c msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" +"the -a, and -r, options to 'git branch' do not take a branch name.\n" "Did you mean to use: -a|-r --list <pattern>?" msgstr "" "“git branch†的 -a å’Œ -r é¸é …ä¸å–分支å稱。\n" @@ -3727,9 +3737,8 @@ msgstr "" #: builtin/branch.c msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." -msgstr "" -"ä¸å†æ”¯æ´é¸é … “--set-upstreamâ€ã€‚請改用 “--track†或 “--set-upstream-toâ€ã€‚" +"'--set-upstream-to' instead" +msgstr "ä¸å†æ”¯æ´é¸é … “--set-upstreamâ€ã€‚請改用 “--track†或 “--set-upstream-toâ€" #: builtin/bugreport.c msgid "git version:\n" @@ -3812,6 +3821,11 @@ msgstr "指定è‡èŸ²å ±å‘Šæª”案的目的地" msgid "specify a strftime format suffix for the filename(s)" msgstr "指定用於檔åçš„ strftime æ ¼å¼å¾Œç¶´" +#: builtin/bugreport.c +#, c-format +msgid "unknown argument `%s'" +msgstr "未知引數 “%sâ€" + #: builtin/bugreport.c builtin/diagnose.c #, c-format msgid "could not create leading directories for '%s'" @@ -3951,6 +3965,14 @@ msgstr "git cat-file (-t | -s) [--allow-unknown-type] <object>" #: builtin/cat-file.c msgid "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" +msgstr "" +"git cat-file (--textconv | --filters)\n" +" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" + +#: builtin/cat-file.c +msgid "" "git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" "objects]\n" " [--buffer] [--follow-symlinks] [--unordered]\n" @@ -3962,14 +3984,6 @@ msgstr "" " [--textconv | --filters] [-Z]" #: builtin/cat-file.c -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" - -#: builtin/cat-file.c msgid "Check object existence or emit object contents" msgstr "檢查物件的å˜åœ¨ç‹€æ…‹ï¼Œæˆ–輸出物件內容" @@ -4344,6 +4358,11 @@ msgstr "“%s†或 “%s†無法與 %s 一起使用" #: builtin/checkout.c #, c-format +msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" +msgstr "“%sâ€ã€â€œ%s†或 “%s†無法在簽出樹狀物件時使用" + +#: builtin/checkout.c +#, c-format msgid "path '%s' is unmerged" msgstr "路徑 “%s†未åˆä½µ" @@ -4369,7 +4388,7 @@ msgstr "ç„¡æ³•å° â€œ%s†執行 reflog 動作:%s\n" msgid "HEAD is now at" msgstr "HEAD ç›®å‰ä½æ–¼" -#: builtin/checkout.c builtin/clone.c t/helper/test-fast-rebase.c +#: builtin/checkout.c builtin/clone.c msgid "unable to update HEAD" msgstr "無法更新 HEAD" @@ -4630,8 +4649,8 @@ msgid "new-branch" msgstr "new-branch" #: builtin/checkout.c -msgid "new unparented branch" -msgstr "新的,沒有父æäº¤çš„分支" +msgid "new unborn branch" +msgstr "新的未誕生分支" #: builtin/checkout.c builtin/merge.c msgid "update ignored files (default)" @@ -4698,7 +4717,7 @@ msgstr "" msgid "you must specify path(s) to restore" msgstr "æ‚¨å¿…é ˆæŒ‡å®šè¦é‚„原的路徑" -#: builtin/checkout.c builtin/clone.c builtin/remote.c +#: builtin/checkout.c builtin/clone.c builtin/remote.c builtin/replay.c #: builtin/submodule--helper.c builtin/worktree.c msgid "branch" msgstr "branch" @@ -4939,10 +4958,6 @@ msgid "" msgstr "" "clean.requireForce é è¨ç‚º true 且未æä¾› -iã€-n 或 -f é¸é …,拒絕執行清ç†å‹•作" -#: builtin/clean.c -msgid "-x and -X cannot be used together" -msgstr "-x å’Œ -X ä¸èƒ½åŒæ™‚使用" - #: builtin/clone.c msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<options>] [--] <repo> [<dir>]" @@ -5021,7 +5036,7 @@ msgstr "簽出 <branch> è€Œä¸æ˜¯é 端 HEAD" msgid "path to git-upload-pack on the remote" msgstr "é 端 git-upload-pack 路徑" -#: builtin/clone.c builtin/fetch.c builtin/grep.c builtin/pull.c +#: builtin/clone.c builtin/fetch.c builtin/pull.c msgid "depth" msgstr "depth" @@ -5034,6 +5049,7 @@ msgid "create a shallow clone since a specific time" msgstr "建立從指定時間到ç¾åœ¨çš„æ·ºå±¤è¤‡è£½" #: builtin/clone.c builtin/fetch.c builtin/pull.c builtin/rebase.c +#: builtin/replay.c msgid "revision" msgstr "revision" @@ -5061,6 +5077,10 @@ msgstr "gitdir" msgid "separate git dir from working tree" msgstr "git 目錄和工作å€åˆ†é›¢" +#: builtin/clone.c builtin/init-db.c +msgid "specify the reference format to use" +msgstr "指定è¦ä½¿ç”¨çš„å¼•ç”¨æ ¼å¼" + #: builtin/clone.c msgid "key=value" msgstr "key=value" @@ -5210,11 +5230,10 @@ msgstr "å¤ªå¤šåƒæ•¸ã€‚" msgid "You must specify a repository to clone." msgstr "æ‚¨å¿…é ˆæŒ‡å®šè¦è¤‡è£½çš„版本庫。" -#: builtin/clone.c -msgid "" -"--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" -"exclude" -msgstr "--bundle-uri 與 --depthã€--shallow-since å’Œ --shallow-exclude ä¸ç›¸å®¹" +#: builtin/clone.c builtin/init-db.c setup.c +#, c-format +msgid "unknown ref storage format '%s'" +msgstr "æœªçŸ¥çš„å¼•ç”¨å„²å˜æ ¼å¼ “%sâ€" #: builtin/clone.c #, c-format @@ -5375,14 +5394,14 @@ msgid "" "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" msgstr "" "git commit-graph write [--object-dir <dir>] [--append]\n" " [--split[=<strategy>]] [--reachable | --stdin-packs | " "--stdin-commits]\n" " [--changed-paths] [--[no-]max-new-filters <n>] [--" "[no-]progress]\n" -" <split options>" +" <split-options>" #: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c msgid "dir" @@ -5403,6 +5422,11 @@ msgstr "無法開啟æäº¤åœ–å½¢ '%s'" #: builtin/commit-graph.c #, c-format +msgid "could not open commit-graph chain '%s'" +msgstr "無法開啟æäº¤åœ–éˆ â€œ%sâ€" + +#: builtin/commit-graph.c +#, c-format msgid "unrecognized --split argument, %s" msgstr "無法è˜åˆ¥çš„ --split åƒæ•¸ï¼Œ%s" @@ -5642,10 +5666,6 @@ msgid "Failed to update main cache tree" msgstr "ä¸èƒ½æ›´æ–°æ¨¹çš„主快å–" #: builtin/commit.c -msgid "unable to write new_index file" -msgstr "無法寫 new_index 檔案" - -#: builtin/commit.c msgid "cannot do a partial commit during a merge." msgstr "在åˆä½µéŽç¨‹ä¸ä¸èƒ½åšéƒ¨åˆ†æäº¤ã€‚" @@ -6139,11 +6159,11 @@ msgstr "æäº¤èªªæ˜Žå…§æ–‡ç©ºç™½ï¼Œä¸æ¢æäº¤ä½œæ¥ã€‚\n" #: builtin/commit.c msgid "" "repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" +"new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover." msgstr "" -"版本庫已更新,但無法寫 new_index 檔案。檢查是å¦ç£ç¢Ÿå·²æ»¿æˆ–\n" -"ç£ç¢Ÿé…é¡å·²è€—盡,然後執行 \"git restore --staged :/\" 復原。" +"版本庫已更新,但無法寫入新的索引檔案。請檢查ç£ç¢Ÿæ˜¯å¦\n" +"已滿或ç£ç¢Ÿé…é¡å·²è€—盡,然後執行 “git restore --staged :/†復原。" #: builtin/config.c msgid "git config [<options>]" @@ -7954,6 +7974,10 @@ msgstr "清除未引用的物件" msgid "pack unreferenced objects separately" msgstr "ç¨ç«‹å°è£ç„¡å¼•用物件" +#: builtin/gc.c builtin/repack.c +msgid "with --cruft, limit the size of new cruft packs" +msgstr "æé… --cruft,é™åˆ¶æ–°å»¢æ£„å°è£çš„大å°" + #: builtin/gc.c msgid "be more thorough (increased runtime)" msgstr "æ›´å¾¹åº•ï¼ˆå¢žåŠ åŸ·è¡Œæ™‚é–“ï¼‰" @@ -8168,14 +8192,6 @@ msgstr "無法執行 “crontabâ€ï¼›æ‚¨çš„系統å¯èƒ½ä¸æ”¯æ´ “cronâ€" msgid "'crontab' died" msgstr "“crontabâ€ çµæŸé‹ä½œ" -#: builtin/gc.c -msgid "failed to start systemctl" -msgstr "無法啟動 systemctl" - -#: builtin/gc.c -msgid "failed to run systemctl" -msgstr "無法執行 systemctl" - #: builtin/gc.c builtin/worktree.c #, c-format msgid "failed to delete '%s'" @@ -8187,6 +8203,14 @@ msgid "failed to flush '%s'" msgstr "排清 '%s' 失敗" #: builtin/gc.c +msgid "failed to start systemctl" +msgstr "無法啟動 systemctl" + +#: builtin/gc.c +msgid "failed to run systemctl" +msgstr "無法執行 systemctl" + +#: builtin/gc.c #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "無法è˜åˆ¥çš„ --scheduler 引數 '%s'" @@ -8217,6 +8241,10 @@ msgid "scheduler to trigger git maintenance run" msgstr "è¦è§¸ç™¼ git maintenance run 的排程器" #: builtin/gc.c +msgid "failed to set up maintenance schedule" +msgstr "無法è¨å®šç¶è·æŽ’程" + +#: builtin/gc.c msgid "failed to add repo to global config" msgstr "ç„¡æ³•å°‡ç‰ˆæœ¬åº«åŠ è‡³å…¨åŸŸè¨å®š" @@ -8254,6 +8282,11 @@ msgstr "ç„¡æ³•è®€å–æ¨¹ï¼ˆ%s)" #: builtin/grep.c #, c-format +msgid "unable to read tree %s" +msgstr "ç„¡æ³•è®€å– %s 樹狀物件" + +#: builtin/grep.c +#, c-format msgid "unable to grep from object of type %s" msgstr "無法抓å–來自於 %s 類型的物件" @@ -8312,8 +8345,8 @@ msgid "search in subdirectories (default)" msgstr "在å目錄ä¸å°‹æ‰¾ï¼ˆé è¨å€¼ï¼‰" #: builtin/grep.c -msgid "descend at most <depth> levels" -msgstr "最多以指定的深度å‘下尋找" +msgid "descend at most <n> levels" +msgstr "最多å‘下尋找 <n> 層" #: builtin/grep.c msgid "use extended POSIX regular expressions" @@ -8774,11 +8807,6 @@ msgstr "解壓縮嚴é‡çš„ä¸ä¸€è‡´" msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "ç™¼ç¾ %s å‡ºç¾ SHA1 è¡çªï¼" -#: builtin/index-pack.c builtin/pack-objects.c -#, c-format -msgid "unable to read %s" -msgstr "ä¸èƒ½è®€ %s" - #: builtin/index-pack.c #, c-format msgid "cannot read existing object info %s" @@ -8952,11 +8980,13 @@ msgstr "åœ¨æ‰“åŒ…ç‰©ä»¶ä¸ fsck 檢查發生錯誤" msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" msgstr "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" +" [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" " [--shared[=<permissions>]] [<directory>]" @@ -9009,11 +9039,11 @@ msgstr "--separate-git-dir 與純版本庫ä¸ç›¸å®¹" #: builtin/interpret-trailers.c msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer <token>[(=|:)<value>])...]\n" +" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" #: builtin/interpret-trailers.c @@ -9025,6 +9055,10 @@ msgid "trim empty trailers" msgstr "刪除空的尾部署å" #: builtin/interpret-trailers.c +msgid "placement" +msgstr "placement" + +#: builtin/interpret-trailers.c msgid "where to place the new trailer" msgstr "在哪裡放置新的尾部署å" @@ -9041,20 +9075,20 @@ msgid "output only the trailers" msgstr "åªè¼¸å‡ºå°¾éƒ¨ç½²å" #: builtin/interpret-trailers.c -msgid "do not apply config rules" -msgstr "ä¸è¦å¥—用組態è¨å®šè¦å‰‡" +msgid "do not apply trailer.* configuration variables" +msgstr "ä¸å¥—用 trailer.* 組態變數" #: builtin/interpret-trailers.c -msgid "join whitespace-continued values" -msgstr "連線空白折行的值" +msgid "reformat multiline trailer values as single-line values" +msgstr "將多列尾注值 (trailer values) 釿–°æ ¼å¼åŒ–為單列值" #: builtin/interpret-trailers.c -msgid "set parsing options" -msgstr "è¨å®šè§£æžé¸é …" +msgid "alias for --only-trailers --only-input --unfold" +msgstr "--only-trailers --only-input --unfold 的別å" #: builtin/interpret-trailers.c -msgid "do not treat --- specially" -msgstr "ä¸è¦å° --- 特殊處ç†" +msgid "do not treat \"---\" as the end of input" +msgstr "ä¸è¦æŠŠ “---†當作輸入çµå°¾" #: builtin/interpret-trailers.c msgid "trailer(s) to add" @@ -9111,7 +9145,7 @@ msgid "" "<file>" msgstr "追蹤 <é–‹å§‹>,<çµæŸ> 範åœä¸æ©«åˆ—或 <檔案> ä¸> :<函數å稱> 的變化å²" -#: builtin/log.c builtin/shortlog.c bundle.c +#: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c #, c-format msgid "unrecognized argument: %s" msgstr "無法è˜åˆ¥çš„åƒæ•¸ï¼š%s" @@ -9167,6 +9201,11 @@ msgid "not a range" msgstr "䏿˜¯ä¸€å€‹ç¯„åœ" #: builtin/log.c +#, c-format +msgid "unable to read branch description file '%s'" +msgstr "無法讀å–分支æè¿°æª” “%sâ€" + +#: builtin/log.c msgid "cover letter needs email format" msgstr "附函需è¦ä¿¡ä»¶ä½å€æ ¼å¼" @@ -9293,6 +9332,10 @@ msgid "generate parts of a cover letter based on a branch's description" msgstr "基於分支æè¿°ç”¢ç”Ÿéƒ¨åˆ†é™„函" #: builtin/log.c +msgid "use branch description from file" +msgstr "從檔案讀å–分支æè¿°ä¸¦ä½¿ç”¨" + +#: builtin/log.c msgid "use [<prefix>] instead of [PATCH]" msgstr "使用 [<å‰ç¶´>] 代替 [PATCH]" @@ -9845,11 +9888,22 @@ msgstr "" "git merge-file [<é¸é …>] [-L <檔案1> [-L <åˆå§‹> [-L <åå—2>]]] <檔案1> <åˆå§‹æ–‡" "ä»¶> <檔案2>" +#: builtin/merge-file.c diff.c +msgid "" +"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " +"\"histogram\"" +msgstr "" +"diff-algorithm é¸é …有 \"myers\"ã€\"minimal\"ã€\"patience\" å’Œ \"histogram\"" + #: builtin/merge-file.c msgid "send results to standard output" msgstr "å°‡çµæžœå‚³é€åˆ°æ¨™æº–輸出" #: builtin/merge-file.c +msgid "use object IDs instead of filenames" +msgstr "使用物件 ID å–代檔å" + +#: builtin/merge-file.c msgid "use a diff3 based merge" msgstr "使用基於 diff3 çš„åˆä½µ" @@ -9869,6 +9923,14 @@ msgstr "如果è¡çªï¼Œä½¿ç”¨ä»–們的版本" msgid "for conflicts, use a union version" msgstr "如果è¡çªï¼Œä½¿ç”¨è¯åˆç‰ˆæœ¬" +#: builtin/merge-file.c diff.c +msgid "<algorithm>" +msgstr "<演算法>" + +#: builtin/merge-file.c diff.c +msgid "choose a diff algorithm" +msgstr "鏿“‡ä¸€å€‹å·®ç•°æ¼”算法" + #: builtin/merge-file.c msgid "for conflicts, use this marker size" msgstr "如果è¡çªï¼Œä½¿ç”¨æŒ‡å®šé•·åº¦çš„æ¨™è¨˜" @@ -9881,6 +9943,15 @@ msgstr "ä¸è¦è¦å‘Šè¡çª" msgid "set labels for file1/orig-file/file2" msgstr "為 檔案1/åˆå§‹æª”案/檔案2 è¨å®šæ¨™ç±¤" +#: builtin/merge-file.c +#, c-format +msgid "object '%s' does not exist" +msgstr "物件 “%s†ä¸å˜åœ¨" + +#: builtin/merge-file.c +msgid "Could not write object file" +msgstr "無法寫入物件檔案" + #: builtin/merge-recursive.c #, c-format msgid "unknown option %s" @@ -9959,13 +10030,22 @@ msgstr "執行多次åˆä½µï¼Œä¸€æ¬¡åŸ·è¡Œè¼¸å…¥ä¸€åˆ—" msgid "specify a merge-base for the merge" msgstr "指定用來åˆä½µçš„åˆä½µåŸºåº•" +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c +msgid "option=value" +msgstr "option=value" + +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c +msgid "option for selected merge strategy" +msgstr "所é¸çš„åˆä½µç–略的é¸é …" + #: builtin/merge-tree.c msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge 和其他所有é¸é …都ä¸ç›¸å®¹" -#: builtin/merge-tree.c -msgid "--merge-base is incompatible with --stdin" -msgstr "--merge-base 與 --stdin ä¸ç›¸å®¹" +#: builtin/merge-tree.c builtin/merge.c +#, c-format +msgid "unknown strategy option: -X%s" +msgstr "未知的ç–ç•¥é¸é …:-X%s" #: builtin/merge-tree.c builtin/notes.c #, c-format @@ -10054,14 +10134,6 @@ msgstr "ç–ç•¥" msgid "merge strategy to use" msgstr "è¦ä½¿ç”¨çš„åˆä½µç–ç•¥" -#: builtin/merge.c builtin/pull.c -msgid "option=value" -msgstr "option=value" - -#: builtin/merge.c builtin/pull.c -msgid "option for selected merge strategy" -msgstr "所é¸çš„åˆä½µç–略的é¸é …" - #: builtin/merge.c msgid "merge commit message (for a non-fast-forward merge)" msgstr "åˆä½µçš„æäº¤èªªæ˜Žï¼ˆé‡å°éžå¿«è½‰å¼åˆä½µï¼‰" @@ -10133,7 +10205,7 @@ msgstr "'%s' 沒有指å‘一個æäº¤" msgid "Bad branch.%s.mergeoptions string: %s" msgstr "壞的 branch.%s.mergeoptions å—串:%s" -#: builtin/merge.c builtin/stash.c merge-recursive.c +#: builtin/merge.c merge-recursive.c msgid "Unable to write index." msgstr "ä¸èƒ½å¯«å…¥ç´¢å¼•。" @@ -10143,11 +10215,6 @@ msgstr "未處ç†å…©å€‹é åˆä½µä¹‹å¤–的任何動作。" #: builtin/merge.c #, c-format -msgid "unknown strategy option: -X%s" -msgstr "未知的ç–ç•¥é¸é …:-X%s" - -#: builtin/merge.c t/helper/test-fast-rebase.c -#, c-format msgid "unable to write %s" msgstr "ä¸èƒ½å¯« %s" @@ -10504,8 +10571,8 @@ msgid "can not move directory into itself" msgstr "ä¸èƒ½å°‡ç›®éŒ„移動到自身" #: builtin/mv.c -msgid "cannot move directory over file" -msgstr "ä¸èƒ½å°‡ç›®éŒ„移動到檔案" +msgid "destination already exists" +msgstr "目的地已å˜åœ¨" #: builtin/mv.c msgid "source directory is empty" @@ -11134,6 +11201,11 @@ msgstr "ä¸ä¸€è‡´çš„差異計數" #: builtin/pack-objects.c #, c-format +msgid "invalid pack.allowPackReuse value: '%s'" +msgstr "無效的 pack.allowPackReuse 值:“%sâ€" + +#: builtin/pack-objects.c +#, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" @@ -11433,10 +11505,6 @@ msgid "--thin cannot be used to build an indexable pack" msgstr "--thin ä¸èƒ½ç”¨æ–¼å»ºç«‹ä¸€å€‹å¯ç´¢å¼•包" #: builtin/pack-objects.c -msgid "cannot use --filter without --stdout" -msgstr "ä¸èƒ½åœ¨æ²’有 --stdout 的情æ³ä¸‹ä½¿ç”¨ --filter" - -#: builtin/pack-objects.c msgid "cannot use --filter with --stdin-packs" msgstr "無法將 --filter åŠ --stdin-packs çµåˆä½¿ç”¨" @@ -11453,10 +11521,6 @@ msgid "cannot use --stdin-packs with --cruft" msgstr "無法將 --stdin-packs 與 --cruft 組åˆä½¿ç”¨" #: builtin/pack-objects.c -msgid "cannot use --max-pack-size with --cruft" -msgstr "無法將 --max-pack-size 與 --cruft 組åˆä½¿ç”¨" - -#: builtin/pack-objects.c msgid "Enumerating objects" msgstr "枚舉物件" @@ -11464,10 +11528,10 @@ msgstr "枚舉物件" #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" +"reused %<PRIu32> (from %<PRIuMAX>)" msgstr "" "總共 %<PRIu32> (差異 %<PRIu32>),復用 %<PRIu32> (差異 %<PRIu32>),é‡ç”¨åŒ… " -"%<PRIu32>" +"%<PRIu32> (總共 %<PRIuMAX>)" #: builtin/pack-redundant.c msgid "" @@ -12546,7 +12610,7 @@ msgstr "沒有æ£åœ¨é€²è¡Œçš„é‡å®šåŸºåº•?" msgid "The --edit-todo action can only be used during interactive rebase." msgstr "動作 --edit-todo åªèƒ½ç”¨åœ¨äº’å‹•å¼é‡å®šåŸºåº•éŽç¨‹ä¸ã€‚" -#: builtin/rebase.c t/helper/test-fast-rebase.c +#: builtin/rebase.c msgid "Cannot read HEAD" msgstr "ä¸èƒ½è®€å– HEAD" @@ -12591,16 +12655,6 @@ msgid "switch `C' expects a numerical value" msgstr "é–‹é—œ `C' 期望一個數å—值" #: builtin/rebase.c -msgid "--strategy requires --merge or --interactive" -msgstr "--strategy éœ€è¦ --merge 或 --interactive" - -#: builtin/rebase.c -msgid "" -"apply options are incompatible with rebase.autoSquash. Consider adding --no-" -"autosquash" -msgstr "apply é¸é …與 rebase.autoSquash ä¸ç›¸å®¹ã€‚è«‹è€ƒæ…®åŠ ä¸Š --no-autosquash" - -#: builtin/rebase.c msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -13085,7 +13139,7 @@ msgid "" msgid_plural "" "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n" "to delete them, use:" -msgstr[0] "注æ„:ref/remotes 層級之外的一個分支未被移除。è¦åˆªé™¤å®ƒï¼Œä½¿ç”¨ï¼š" +msgstr[0] "注æ„:refs/remotes/ 層級之外的一個分支未被移除。è¦åˆªé™¤å®ƒï¼Œä½¿ç”¨ï¼š" #: builtin/remote.c #, c-format @@ -13442,6 +13496,11 @@ msgid "could not remove stale bitmap: %s" msgstr "ç„¡æ³•ç§»é™¤éŽæ™‚ä½åœ–:%s" #: builtin/repack.c +#, c-format +msgid "pack prefix %s does not begin with objdir %s" +msgstr "å°åŒ…å‰ç¶´ %s ä¸ä»¥ objdir %s é–‹é " + +#: builtin/repack.c msgid "pack everything in a single pack" msgstr "所有內容打包到一個包檔案ä¸" @@ -13542,17 +13601,21 @@ msgid "pack prefix to store a pack containing pruned objects" msgstr "å°è£å‰ç¶´ï¼Œå„²å˜ç‚ºåŒ…å«éŽæ™‚物件的套件包" #: builtin/repack.c +msgid "pack prefix to store a pack containing filtered out objects" +msgstr "å°‡å‰ç¶´é€²è¡ŒåŒ…è£ï¼Œå„²å˜ç‚ºåŒ…å«å·²éŽæ¿¾ç‰©ä»¶çš„å°è£" + +#: builtin/repack.c msgid "cannot delete packs in a precious-objects repo" msgstr "ä¸èƒ½åˆªé™¤çå“版本庫ä¸çš„å°åŒ…" #: builtin/repack.c -msgid "Nothing new to pack." -msgstr "æ²’æœ‰æ–°çš„è¦æ‰“包。" +#, c-format +msgid "option '%s' can only be used along with '%s'" +msgstr "“%s†é¸é …åªèƒ½èˆ‡ “%s†一起使用" #: builtin/repack.c -#, c-format -msgid "pack prefix %s does not begin with objdir %s" -msgstr "å°åŒ…å‰ç¶´ %s ä¸ä»¥ objdir %s é–‹é " +msgid "Nothing new to pack." +msgstr "æ²’æœ‰æ–°çš„è¦æ‰“包。" #: builtin/repack.c #, c-format @@ -13805,6 +13868,86 @@ msgstr "--convert-graft-file ä¸å¸¶åƒæ•¸" msgid "only one pattern can be given with -l" msgstr "åªèƒ½ç‚º -l æä¾›ä¸€å€‹æ¨¡å¼" +#: builtin/replay.c +msgid "need some commits to replay" +msgstr "需è¦ä¸€äº›æäº¤æ‰èƒ½é‡æ”¾" + +#: builtin/replay.c +msgid "--onto and --advance are incompatible" +msgstr "--onto å’Œ --advance ä¸ç›¸å®¹" + +#: builtin/replay.c +msgid "all positive revisions given must be references" +msgstr "æä¾›çš„æ‰€æœ‰æ£å‘ä¿®è¨‚é›†å¿…é ˆç‚ºå¼•ç”¨" + +#: builtin/replay.c +msgid "argument to --advance must be a reference" +msgstr "傳入 --advance çš„å¼•æ•¸å¿…é ˆç‚ºå¼•ç”¨" + +#: builtin/replay.c +msgid "" +"cannot advance target with multiple sources because ordering would be ill-" +"defined" +msgstr "ç„¡æ³•ç”¨å¤šå€‹ä¾†æºæ¼”進目的地,以å…無法確定排åº" + +#: builtin/replay.c +msgid "" +"cannot implicitly determine whether this is an --advance or --onto operation" +msgstr "無法å‡è¨é€™æ˜¯ --advance 還是 --onto 動作" + +#: builtin/replay.c +msgid "" +"cannot advance target with multiple source branches because ordering would " +"be ill-defined" +msgstr "無法由多個來æºåˆ†æ”¯æ¼”進目的地,以å…無法確定排åº" + +#: builtin/replay.c +msgid "cannot implicitly determine correct base for --onto" +msgstr "無法å‡è¨ --onto çš„æ£ç¢ºåŸºåº•" + +#: builtin/replay.c +msgid "" +"(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." +msgstr "" +"(實驗性功能ï¼ï¼‰git replay ([--contained] --onto <newbase> | --advance " +"<branch>) <revision-range>..." + +#: builtin/replay.c +msgid "make replay advance given branch" +msgstr "åœ¨æŒ‡å®šåˆ†æ”¯ä¸Šé€²è¡Œé‡æ”¾æ¼”進" + +#: builtin/replay.c +msgid "replay onto given commit" +msgstr "釿”¾åˆ°æŒ‡å®šæäº¤" + +#: builtin/replay.c +msgid "advance all branches contained in revision-range" +msgstr "演進所有包å«åœ¨ revision-range ä¸çš„分支" + +#: builtin/replay.c +msgid "option --onto or --advance is mandatory" +msgstr "å¿…é ˆå‚³å…¥ --onto 或 --advance é¸é …" + +#: builtin/replay.c +#, c-format +msgid "" +"some rev walking options will be overridden as '%s' bit in 'struct rev_info' " +"will be forced" +msgstr "å°‡è¦†å¯«éƒ¨åˆ†ä¿®è¨‚ç‰ˆéæ·é¸é …,強制使用 “struct rev_info†的 “%s†ä½å…ƒ" + +#: builtin/replay.c +msgid "error preparing revisions" +msgstr "無法準備修訂集" + +#: builtin/replay.c +msgid "replaying down to root commit is not supported yet!" +msgstr "å°šä¸æ”¯æ´é‡æ”¾åˆ°æ ¹æäº¤ï¼" + +#: builtin/replay.c +msgid "replaying merge commits is not supported yet!" +msgstr "å°šä¸æ”¯æ´é‡æ”¾åˆä½µæäº¤ï¼" + #: builtin/rerere.c msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" @@ -14067,23 +14210,15 @@ msgstr "--prefix éœ€è¦ 1 個引數" msgid "unknown mode for --abbrev-ref: %s" msgstr "--abbrev-ref çš„æ¨¡å¼æœªçŸ¥ï¼š%s" -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --branches" -msgstr "--exclude-hidden 無法與 --branches åŒæ™‚使用" - -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --tags" -msgstr "--exclude-hidden 無法與 --tags åŒæ™‚使用" - -#: builtin/rev-parse.c revision.c -msgid "--exclude-hidden cannot be used together with --remotes" -msgstr "--exclude-hidden 無法與 --remotes åŒæ™‚使用" - #: builtin/rev-parse.c setup.c msgid "this operation must be run in a work tree" msgstr "è©²å‹•ä½œå¿…é ˆåœ¨ä¸€å€‹å·¥ä½œå€ä¸åŸ·è¡Œ" #: builtin/rev-parse.c +msgid "Could not read the index" +msgstr "無法讀å–索引" + +#: builtin/rev-parse.c #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "--show-object-format çš„æ¨¡å¼æœªçŸ¥ï¼š%s" @@ -14503,19 +14638,41 @@ msgstr "未知的雜湊算法" #: builtin/show-ref.c msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference]\n" +"git show-ref [--head] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" " [--heads] [--] [<pattern>...]" #: builtin/show-ref.c +msgid "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" +msgstr "" +"git show-ref --verify [-q | --quiet] [-d | --dereference]\n" +" [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" +" [--] [<ref>...]" + +#: builtin/show-ref.c msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<模å¼>]" #: builtin/show-ref.c +msgid "git show-ref --exists <ref>" +msgstr "git show-ref --exists <ref>" + +#: builtin/show-ref.c +msgid "reference does not exist" +msgstr "引用ä¸å˜åœ¨" + +#: builtin/show-ref.c +msgid "failed to look up reference" +msgstr "無法查詢引用" + +#: builtin/show-ref.c msgid "only show tags (can be combined with heads)" msgstr "åªé¡¯ç¤ºæ¨™ç±¤ï¼ˆå¯ä»¥å’Œé 共用)" @@ -14524,6 +14681,10 @@ msgid "only show heads (can be combined with tags)" msgstr "åªé¡¯ç¤ºé (å¯ä»¥å’Œæ¨™ç±¤å…±ç”¨ï¼‰" #: builtin/show-ref.c +msgid "check for reference existence without resolving" +msgstr "檢查引用是å¦å˜åœ¨ä½†ä¸è§£æž" + +#: builtin/show-ref.c msgid "stricter reference checking, requires exact ref path" msgstr "æ›´åš´æ ¼çš„å¼•ç”¨æª¢æ¸¬ï¼Œéœ€è¦ç²¾ç¢ºçš„引用路徑" @@ -15511,6 +15672,10 @@ msgstr "" "shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] " "[--] [<path>...]" +#: builtin/submodule--helper.c submodule.c +msgid "Failed to resolve HEAD as a valid ref." +msgstr "無法將 HEAD è§£æžç‚ºæœ‰æ•ˆå¼•用。" + #: builtin/submodule--helper.c msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<options>] [<path>...]" @@ -16087,6 +16252,10 @@ msgid "write index in this format" msgstr "ä»¥é€™ç¨®æ ¼å¼å¯«å…¥ç´¢å¼•å€" #: builtin/update-index.c +msgid "report on-disk index format version" +msgstr "å›žå ±ç£ç¢Ÿä¸Šç´¢å¼•æ ¼å¼çš„版本" + +#: builtin/update-index.c msgid "enable or disable split index" msgstr "啟用或åœç”¨ç´¢å¼•分割" @@ -16119,6 +16288,16 @@ msgid "clear fsmonitor valid bit" msgstr "清除 fsmonitor 有效ä½" #: builtin/update-index.c +#, c-format +msgid "%d\n" +msgstr "%d\n" + +#: builtin/update-index.c +#, c-format +msgid "index-version: was %d, set to %d" +msgstr "index-version:曾是 %d,已è¨ç‚º %d" + +#: builtin/update-index.c msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -16303,14 +16482,14 @@ msgstr "沒有å¯èƒ½çš„來æºåˆ†æ”¯ï¼ŒæŽ¨æ¸¬ç‚º “--orphanâ€" #: builtin/worktree.c #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan -b %s %s\n" msgstr "" "如果您是想è¦åœ¨é€™å€‹ç‰ˆæœ¬åº«å»ºç«‹ä¸€å€‹å·¥ä½œå€ï¼Œè£¡é¢åŒ…å«ä¸€å€‹\n" -"å¤ç«‹åˆ†æ”¯ï¼ˆå³æ²’有æäº¤çš„分支),å¯ä»¥ä½¿ç”¨ --orphan é”到\n" +"æœªèª•ç”Ÿåˆ†æ”¯ï¼ˆå³æ²’有æäº¤çš„分支),å¯ä»¥ä½¿ç”¨ --orphan é”到\n" "這個效果:\n" "\n" " git worktree add --orphan -b %s %s\n" @@ -16318,14 +16497,14 @@ msgstr "" #: builtin/worktree.c #, c-format msgid "" -"If you meant to create a worktree containing a new orphan branch\n" +"If you meant to create a worktree containing a new unborn branch\n" "(branch with no commits) for this repository, you can do so\n" "using the --orphan flag:\n" "\n" " git worktree add --orphan %s\n" msgstr "" "如果您是想è¦åœ¨é€™å€‹ç‰ˆæœ¬åº«å»ºç«‹ä¸€å€‹å·¥ä½œå€ï¼Œè£¡é¢åŒ…å«ä¸€å€‹\n" -"å¤ç«‹åˆ†æ”¯ï¼ˆå³æ²’有æäº¤çš„分支),å¯ä»¥ä½¿ç”¨ --orphan é”到\n" +"æœªèª•ç”Ÿåˆ†æ”¯ï¼ˆå³æ²’有æäº¤çš„分支),å¯ä»¥ä½¿ç”¨ --orphan é”到\n" "這個效果:\n" "\n" " git worktree add --orphan %s\n" @@ -16397,6 +16576,11 @@ msgstr "æ£åœ¨åˆå§‹åŒ–" #: builtin/worktree.c #, c-format +msgid "could not find created worktree '%s'" +msgstr "找ä¸åˆ°å»ºç«‹çš„工作å€ã€Œ%sã€" + +#: builtin/worktree.c +#, c-format msgid "Preparing worktree (new branch '%s')" msgstr "準備工作å€ï¼ˆæ–°åˆ†æ”¯ '%s')" @@ -16434,17 +16618,12 @@ msgstr "" #: builtin/worktree.c msgid "" "No local or remote refs exist despite at least one remote\n" -"present, stopping; use 'add -f' to overide or fetch a remote first" +"present, stopping; use 'add -f' to override or fetch a remote first" msgstr "" "å³ä½¿æœ‰æä¾›ä¸€å€‹é 端,å»ä¸å˜åœ¨æœ¬æ©Ÿæˆ–é 端引用,\n" "æ•…åœæ¢ã€‚使用 “add -f†先覆蓋或抓å–é 端" #: builtin/worktree.c -#, c-format -msgid "'%s' and '%s' cannot be used together" -msgstr "ç„¡æ³•åŒæ™‚使用 “%s†和 “%sâ€" - -#: builtin/worktree.c msgid "checkout <branch> even if already checked out in other worktree" msgstr "簽出 <分支>,å³ä½¿å·²ç¶“被簽出到其它工作å€" @@ -16457,8 +16636,8 @@ msgid "create or reset a branch" msgstr "建立或é‡è¨ä¸€å€‹åˆ†æ”¯" #: builtin/worktree.c -msgid "create unborn/orphaned branch" -msgstr "建立尚無內容(å¤ç«‹ï¼‰çš„分支" +msgid "create unborn branch" +msgstr "建立未誕生分支" #: builtin/worktree.c msgid "populate the new working tree" @@ -16487,12 +16666,8 @@ msgstr "「%sã€ã€ã€Œ%sã€å’Œã€Œ%sã€é¸é …ä¸å¾—åŒæ™‚使用" #: builtin/worktree.c #, c-format -msgid "options '%s', and '%s' cannot be used together" -msgstr "ç„¡æ³•åŒæ™‚使用 “%s†和 “%s†é¸é …" - -#: builtin/worktree.c -msgid "<commit-ish>" -msgstr "<æäº¤æŒ‡ç¤ºå…ƒ>" +msgid "option '%s' and commit-ish cannot be used together" +msgstr "“%s†é¸é …å’Œæäº¤è™Ÿä¸å¾—åŒæ™‚使用" #: builtin/worktree.c msgid "added with --lock" @@ -16828,6 +17003,11 @@ msgstr "終æ¢å€å¡Š id 出ç¾çš„æ™‚é–“æ—©æ–¼é æœŸ" #: chunk-format.c #, c-format +msgid "chunk id %<PRIx32> not %d-byte aligned" +msgstr "å€å¡Š ID %<PRIx32> 沒有以 %d ä½å…ƒçµ„為單ä½å°é½Š" + +#: chunk-format.c +#, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "䏿£ç¢ºçš„å€å¡Šåç§» %<PRIx64> åŠ %<PRIx64>" @@ -16895,8 +17075,8 @@ msgid "Move objects and refs by archive" msgstr "é€éŽæ¸æª”移動物件和引用" #: command-list.h -msgid "Provide content or type and size information for repository objects" -msgstr "æä¾›ç‰ˆæœ¬åº«ç‰©ä»¶çš„內容ã€é¡žåž‹æˆ–大å°" +msgid "Provide contents or details of repository objects" +msgstr "æä¾›ç‰ˆæœ¬åº«ç‰©ä»¶çš„內容或詳細資訊" #: command-list.h msgid "Display gitattributes information" @@ -17276,6 +17456,10 @@ msgid "Create, list, delete refs to replace objects" msgstr "建立ã€åˆ—出ã€åˆªé™¤ç‰©ä»¶å–代引用" #: command-list.h +msgid "EXPERIMENTAL: Replay commits on a new base, works with bare repos too" +msgstr "å¯¦é©—æ€§åŠŸèƒ½ï¼šåœ¨æ–°çš„åŸºåº•é‡æ”¾æäº¤ï¼Œäº¦æ”¯æ´è£¸ç‰ˆæœ¬åº«" + +#: command-list.h msgid "Generates a summary of pending changes" msgstr "生æˆå¾…定更改的摘è¦" @@ -17437,7 +17621,7 @@ msgid "Display version information about Git" msgstr "顯示 Git 的版本資訊" #: command-list.h -msgid "Show logs with difference each commit introduces" +msgid "Show logs with differences each commit introduces" msgstr "顯示æ¯ä¸€å€‹æäº¤å¼•入的差異日誌" #: command-list.h @@ -17593,6 +17777,37 @@ msgid "commit-graph file is too small" msgstr "æäº¤åœ–形檔案太å°" #: commit-graph.c +msgid "commit-graph oid fanout chunk is wrong size" +msgstr "æäº¤åœ–å½¢ OID 扇出å€å¡Šå¤§å°æœ‰èª¤" + +#: commit-graph.c +msgid "commit-graph fanout values out of order" +msgstr "æäº¤åœ–形扇出的數值失åº" + +#: commit-graph.c +msgid "commit-graph OID lookup chunk is the wrong size" +msgstr "æäº¤åœ–å½¢ OID 查詢å€å¡Šçš„大尿œ‰èª¤" + +#: commit-graph.c +msgid "commit-graph commit data chunk is wrong size" +msgstr "æäº¤åœ–形的æäº¤è³‡æ–™å€å¡Šå¤§å°æœ‰èª¤" + +#: commit-graph.c +msgid "commit-graph generations chunk is wrong size" +msgstr "æäº¤åœ–形的世代å€å¡Šå¤§å°æœ‰èª¤" + +#: commit-graph.c +msgid "commit-graph changed-path index chunk is too small" +msgstr "æäº¤åœ–形的更動路徑索引å€å¡ŠéŽå°" + +#: commit-graph.c +#, c-format +msgid "" +"ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" +"graph file" +msgstr "忽略æäº¤åœ–形檔案ä¸éŽå°çš„æ›´å‹•路徑å€å¡Š (%<PRIuMAX> < %<PRIuMAX>)" + +#: commit-graph.c #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "æäº¤åœ–形簽å %X 和簽å %X ä¸ç¬¦åˆ" @@ -17610,13 +17825,29 @@ msgstr "æäº¤åœ–形雜湊版本 %X 和版本 %X ä¸ç¬¦åˆ" #: commit-graph.c #, c-format msgid "commit-graph file is too small to hold %u chunks" -msgstr "commit-graph 檔案ä¸å¤ 放置 %u 個å€å¡Š" +msgstr "æäº¤åœ–形檔案ä¸å¤ 放置 %u 個å€å¡Š" + +#: commit-graph.c +msgid "commit-graph required OID fanout chunk missing or corrupted" +msgstr "æäº¤åœ–形需è¦çš„ OID 扇出å€å¡Šéºå¤±æˆ–æå£ž" + +#: commit-graph.c +msgid "commit-graph required OID lookup chunk missing or corrupted" +msgstr "æäº¤åœ–形需è¦çš„ OID 查詢å€å¡Šéºå¤±æˆ–æå£ž" + +#: commit-graph.c +msgid "commit-graph required commit data chunk missing or corrupted" +msgstr "æäº¤åœ–形需è¦çš„æäº¤è³‡æ–™å€å¡Šéºå¤±æˆ–æå£ž" #: commit-graph.c msgid "commit-graph has no base graphs chunk" msgstr "æäº¤åœ–形沒有基礎圖形å€å¡Š" #: commit-graph.c +msgid "commit-graph base graphs chunk is too small" +msgstr "æäº¤åœ–形的基礎圖形å€å¡ŠéŽå°" + +#: commit-graph.c msgid "commit-graph chain does not match" msgstr "æäº¤åœ–å½¢éˆä¸ç¬¦åˆ" @@ -17626,9 +17857,13 @@ msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "基礎圖 (base graph) ä¸çš„æäº¤æ•¸éŽå¤šï¼š%<PRIuMAX>" #: commit-graph.c +msgid "commit-graph chain file too small" +msgstr "æäº¤åœ–å½¢éˆæª”案éŽå°" + +#: commit-graph.c #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" -msgstr "無效的æäº¤åœ–å½¢éˆï¼šè¡Œ '%s' 䏿˜¯ä¸€å€‹é›œæ¹Šå€¼" +msgstr "無效的æäº¤åœ–å½¢éˆï¼šã€Œ%sã€åˆ—䏿˜¯é›œæ¹Šå€¼" #: commit-graph.c msgid "unable to find all commit-graph files" @@ -17648,6 +17883,14 @@ msgid "commit-graph requires overflow generation data but has none" msgstr "æäº¤åœ–éœ€è¦æ¯”ç›®å‰æ›´å¤šçš„世代資料,但沒有相關資料" #: commit-graph.c +msgid "commit-graph overflow generation data is too small" +msgstr "æäº¤åœ–形的溢出世代資料éŽå°" + +#: commit-graph.c +msgid "commit-graph extra-edges pointer out of bounds" +msgstr "æäº¤åœ–形的延伸邊界指é‡è¶…出範åœ" + +#: commit-graph.c msgid "Loading known commits in commit graph" msgstr "æ£åœ¨è¼‰å…¥æäº¤åœ–ä¸çš„已知æäº¤" @@ -17802,18 +18045,6 @@ msgstr "æäº¤ %s çš„æäº¤åœ–形父æäº¤åˆ—è¡¨éŽæ—©çµ‚æ¢" #: commit-graph.c #, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "æäº¤åœ–å½¢ä¸æäº¤ %s 的世代號是零,但其它地方éžé›¶" - -#: commit-graph.c -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "æäº¤åœ–å½¢ä¸æäº¤ %s 的世代號éžé›¶ï¼Œä½†å…¶å®ƒåœ°æ–¹æ˜¯é›¶" - -#: commit-graph.c -#, c-format msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" msgstr "æäº¤ %s çš„æäº¤åœ–形處於 %<PRIuMAX> < %<PRIuMAX> 世代" @@ -17823,6 +18054,13 @@ msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>" msgstr "æäº¤åœ–å½¢ä¸æäº¤ %s çš„æäº¤æ—¥æœŸæ˜¯ %<PRIuMAX> != %<PRIuMAX>" #: commit-graph.c +#, c-format +msgid "" +"commit-graph has both zero and non-zero generations (e.g., commits '%s' and " +"'%s')" +msgstr "æäº¤åœ–å½¢ä¸åŒ…å« 0 å’Œéž 0 兩個世代號(例如 “%s†和 “%s†æäº¤ï¼‰" + +#: commit-graph.c msgid "Verifying commits in commit graph" msgstr "æ£åœ¨é©—è‰æäº¤åœ–ä¸çš„æäº¤" @@ -17853,6 +18091,11 @@ msgstr "" #: commit.c #, c-format +msgid "commit %s exists in commit-graph but not in the object database" +msgstr "%s æäº¤åœ¨æäº¤åœ–å½¢ä¸ï¼Œä½†ä¸åœ¨ç‰©ä»¶è³‡æ–™åº«ä¸" + +#: commit.c +#, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "æäº¤ %s 有一個éžå¯ä¿¡çš„è²ç¨±ä¾†è‡ª %s çš„ GPG ç°½å。" @@ -18395,11 +18638,6 @@ msgid "unable to resolve config blob '%s'" msgstr "ä¸èƒ½è§£æžè¨å®šç‰©ä»¶ '%s'" #: config.c -#, c-format -msgid "failed to parse %s" -msgstr "è§£æž %s 失敗" - -#: config.c msgid "unable to parse command-line config" msgstr "無法解æžå‘½ä»¤åˆ—ä¸çš„è¨å®š" @@ -18957,10 +19195,6 @@ msgid "--merge-base does not work with ranges" msgstr "--merge-base 跟範åœç„¡æ³•æé…é‹ä½œ" #: diff-lib.c -msgid "--merge-base only works with commits" -msgstr "--merge-base åªèƒ½è·Ÿæäº¤æé…æ‰èƒ½é‹ä½œ" - -#: diff-lib.c msgid "unable to get HEAD" msgstr "ä¸èƒ½å–å¾— HEAD" @@ -19030,6 +19264,11 @@ msgstr "color-moved-ws:allow-indentation-change ä¸èƒ½èˆ‡å…¶å®ƒç©ºç™½å—元模 msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "è¨å®šè®Šæ•¸ 'diff.submodule' 未知的å–值:'%s'" +#: diff.c transport.c +#, c-format +msgid "unknown value for config '%s': %s" +msgstr "è¨å®š '%s' çš„å–值未知:%s" + #: diff.c #, c-format msgid "" @@ -19124,13 +19363,6 @@ msgid "invalid mode '%s' in --color-moved-ws" msgstr "--color-moved-ws ä¸çš„ç„¡æ•ˆæ¨¡å¼ '%s'" #: diff.c -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" -"diff-algorithm é¸é …有 \"myers\"ã€\"minimal\"ã€\"patience\" å’Œ \"histogram\"" - -#: diff.c #, c-format msgid "invalid argument to %s" msgstr "%s çš„åƒæ•¸ç„¡æ•ˆ" @@ -19187,8 +19419,9 @@ msgid "output only the last line of --stat" msgstr "åªè¼¸å‡º --stat 的最後一行" #: diff.c -msgid "<param1,param2>..." -msgstr "<åƒæ•¸1,åƒæ•¸2>..." +#| msgid "<param1,param2>..." +msgid "<param1>,<param2>..." +msgstr "<param1>,<param2>..." #: diff.c msgid "" @@ -19200,8 +19433,8 @@ msgid "synonym for --dirstat=cumulative" msgstr "å’Œ --dirstat=cumulative åŒç¾©" #: diff.c -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "是 --dirstat=files,param1,param2... çš„åŒç¾©è©ž" +msgid "synonym for --dirstat=files,<param1>,<param2>..." +msgstr "是 --dirstat=files,<param1>,<param2>... çš„åŒç¾©è©ž" #: diff.c msgid "warn if changes introduce conflict markers or whitespace errors" @@ -19424,14 +19657,6 @@ msgid "generate diff using the \"histogram diff\" algorithm" msgstr "使用 \"histogram diff\" 演算法生æˆå·®ç•°" #: diff.c -msgid "<algorithm>" -msgstr "<演算法>" - -#: diff.c -msgid "choose a diff algorithm" -msgstr "鏿“‡ä¸€å€‹å·®ç•°æ¼”算法" - -#: diff.c msgid "<text>" msgstr "<æ–‡å—>" @@ -20679,13 +20904,13 @@ msgstr "" "%s" #: merge-ort.c merge-recursive.c -msgid "Failed to execute internal merge" +msgid "failed to execute internal merge" msgstr "無法執行內部åˆä½µ" #: merge-ort.c merge-recursive.c #, c-format -msgid "Unable to add %s to database" -msgstr "ä¸èƒ½æ–°å¢ž %s 至物件庫" +msgid "unable to add %s to database" +msgstr "無法將 %s åŠ é€²è³‡æ–™åº«" #: merge-ort.c merge-recursive.c #, c-format @@ -20850,7 +21075,7 @@ msgstr "" #. conflict in a submodule. The first argument is the submodule #. name, and the second argument is the abbreviated id of the #. commit that needs to be merged. For example: -#. - go to submodule (mysubmodule), and either merge commit abc1234" +#. - go to submodule (mysubmodule), and either merge commit abc1234" #. #: merge-ort.c #, c-format @@ -21186,6 +21411,20 @@ msgstr "多包索引的物件 ID fanout 大å°éŒ¯èª¤" #: midx.c #, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "物件 ID 扇出無åºï¼šfanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" + +#: midx.c +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "多包索引 OID 查詢å€å¡Šçš„大尿œ‰èª¤" + +#: midx.c +msgid "multi-pack-index object offset chunk is the wrong size" +msgstr "多包索引的物件åç§»å€å¡Šå¤§å°æœ‰èª¤" + +#: midx.c +#, c-format msgid "multi-pack-index file %s is too small" msgstr "多包索引檔案 %s 太å°" @@ -21205,20 +21444,24 @@ msgid "multi-pack-index hash version %u does not match version %u" msgstr "multi-pack-index 雜湊版本 %u 與版本 %u ä¸ç¬¦åˆ" #: midx.c -msgid "multi-pack-index missing required pack-name chunk" -msgstr "多包索引缺少必需的包åå€å¡Š" +msgid "multi-pack-index required pack-name chunk missing or corrupted" +msgstr "多包索引所需的å°è£å稱å€å¡Šä¸å˜åœ¨æˆ–æå£ž" #: midx.c -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "多包索引缺少必需的物件 ID fanout å€å¡Š" +msgid "multi-pack-index required OID fanout chunk missing or corrupted" +msgstr "多包索引所需的 OID fanout å€å¡Šä¸å˜åœ¨æˆ–æå£ž" #: midx.c -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "多包索引缺少必需的物件 ID 查詢å€å¡Š" +msgid "multi-pack-index required OID lookup chunk missing or corrupted" +msgstr "多包索引所需的 OID 查詢å€å¡Šä¸å˜åœ¨æˆ–æå£ž" #: midx.c -msgid "multi-pack-index missing required object offsets chunk" -msgstr "多包索引缺少必需的物件ä½ç§»å€å¡Š" +msgid "multi-pack-index required object offsets chunk missing or corrupted" +msgstr "多包索引所需的物件åç§»å€å¡Šä¸å˜åœ¨æˆ–æå£ž" + +#: midx.c +msgid "multi-pack-index pack-name chunk is too short" +msgstr "多包索引的å°è£å稱å€å¡ŠéŽçŸ" #: midx.c #, c-format @@ -21231,10 +21474,23 @@ msgid "bad pack-int-id: %u (%u total packs)" msgstr "錯的 pack-int-id:%u(共有 %u 個包)" #: midx.c +msgid "MIDX does not contain the BTMP chunk" +msgstr "MIDX æœªåŒ…å« BTMP å€å¡Š" + +#: midx.c +#, c-format +msgid "could not load bitmapped pack %<PRIu32>" +msgstr "無法載入ä½åœ–化 (bitmapped) çš„å°è£ %<PRIu32>" + +#: midx.c msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" msgstr "多包索引儲å˜ä¸€å€‹64ä½ä½ç§»ï¼Œä½†æ˜¯ off_t 太å°" #: midx.c +msgid "multi-pack-index large offset out of bounds" +msgstr "多包索引的最大å移超出邊界" + +#: midx.c #, c-format msgid "failed to add packfile '%s'" msgstr "新增 packfile '%s' 失敗" @@ -21334,12 +21590,6 @@ msgid "Looking for referenced packfiles" msgstr "æ£åœ¨å°‹æ‰¾å¼•用的 packfile" #: midx.c -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "物件 ID 扇出無åºï¼šfanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" - -#: midx.c msgid "the midx contains no oid" msgstr "midx 沒有 oid" @@ -21714,7 +21964,7 @@ msgstr "%s [無效物件]" #. TRANSLATORS: This is a line of ambiguous commit #. object output. E.g.: #. * -#. "deadbeef commit 2021-01-01 - Some Commit Message" +#. "deadbeef commit 2021-01-01 - Some Commit Message" #. #: object-name.c #, c-format @@ -21724,7 +21974,7 @@ msgstr "%s æäº¤ %s - %s" #. TRANSLATORS: This is a line of ambiguous #. tag object output. E.g.: #. * -#. "deadbeef tag 2022-01-01 - Some Tag Message" +#. "deadbeef tag 2022-01-01 - Some Tag Message" #. * #. The second argument is the YYYY-MM-DD found #. in the tag. @@ -21741,7 +21991,7 @@ msgstr "%s 標籤 %s - %s" #. tag object output where we couldn't parse #. the tag itself. E.g.: #. * -#. "deadbeef [bad tag, could not parse it]" +#. "deadbeef [bad tag, could not parse it]" #. #: object-name.c #, c-format @@ -21969,6 +22219,10 @@ msgstr "多包ä½åœ–缺少需è¦çš„åå‘索引" msgid "could not open pack %s" msgstr "無法開啟å°åŒ… %s" +#: pack-bitmap.c t/helper/test-read-midx.c +msgid "could not determine MIDX preferred pack" +msgstr "無法確定 MIDX å好的å°è£" + #: pack-bitmap.c #, c-format msgid "preferred pack (%s) is invalid" @@ -21994,6 +22248,11 @@ msgstr "ewah ä½åœ–æå£žï¼šæäº¤ “%s†之ä½åœ–的標é éæˆªæ–·" #: pack-bitmap.c #, c-format +msgid "unable to load pack: '%s', disabling pack-reuse" +msgstr "無法載入「%sã€å°è£ï¼Œåœç”¨ pack-reuse" + +#: pack-bitmap.c +#, c-format msgid "object '%s' not found in type bitmaps" msgstr "在類型ä½åœ–ä¸ï¼Œæ‰¾ä¸åˆ°ã€Œ%sã€ç‰©ä»¶" @@ -22103,6 +22362,14 @@ msgstr "無效的總和檢查碼" msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "%<PRIu64> ä½ç½®çš„修訂版索引 (rev-index) 無效:%<PRIu32> != %<PRIu32>" +#: pack-revindex.c +msgid "multi-pack-index reverse-index chunk is the wrong size" +msgstr "多包索引的åå‘索引å€å¡Šå¤§å°æœ‰èª¤" + +#: pack-revindex.c +msgid "could not determine preferred pack" +msgstr "無法確定å好å°è£" + #: pack-write.c msgid "cannot both write and verify reverse index" msgstr "ç„¡æ³•åŒæ™‚寫入和驗è‰å€’排索引" @@ -22168,16 +22435,6 @@ msgstr "%s 需è¦ä¸€å€‹å€¼" #: parse-options.c #, c-format -msgid "%s is incompatible with %s" -msgstr "%s 與 %s ä¸ç›¸å®¹" - -#: parse-options.c -#, c-format -msgid "%s : incompatible with something else" -msgstr "%s:和其它的ä¸ç›¸å®¹" - -#: parse-options.c -#, c-format msgid "%s takes no value" msgstr "%s ä¸å–值" @@ -22276,6 +22533,11 @@ msgstr " %s" msgid "-NUM" msgstr "-數å—" +#: parse-options.c +#, c-format +msgid "opposite of --no-%s" +msgstr "--no-%s 的相å行為" + #: parse-options.h msgid "expiry-date" msgstr "到期時間" @@ -22313,6 +22575,16 @@ msgid "" "with --pathspec-from-file, pathspec elements are separated with NUL character" msgstr "如使用 --pathspec-from-file,則 <è·¯å¾‘è¦æ ¼> 元件會使用 NUL å—元分隔" +#: parse.c +#, c-format +msgid "bad boolean environment value '%s' for '%s'" +msgstr "「%2$sã€çš„「%1$sã€å¸ƒæž—環境值無效" + +#: parse.c +#, c-format +msgid "failed to parse %s" +msgstr "è§£æž %s 失敗" + #: path.c #, c-format msgid "Could not make %s writable by group" @@ -22371,6 +22643,11 @@ msgstr "%s:'literal' å’Œ 'glob' ä¸ç›¸å®¹" #: pathspec.c #, c-format +msgid "'%s' is outside the directory tree" +msgstr "“%s†在目錄樹之外" + +#: pathspec.c +#, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s:'%s' åœ¨ä½æ–¼ '%s' 的版本庫之外" @@ -22562,11 +22839,6 @@ msgstr "ç„¡æ³•åœ¨ç´¢å¼•ä¸æ–°å¢ž '%s'" #: read-cache.c #, c-format -msgid "unable to stat '%s'" -msgstr "ç„¡æ³•å° %s 執行 stat" - -#: read-cache.c -#, c-format msgid "'%s' appears as both a file and as a directory" msgstr "'%s' çœ‹èµ·ä¾†æ—¢æ˜¯æª”æ¡ˆåˆæ˜¯ç›®éŒ„" @@ -22701,11 +22973,6 @@ msgstr "ç„¡æ³•è½‰æ›æˆç¨€ç–索引" #: read-cache.c #, c-format -msgid "could not stat '%s'" -msgstr "ä¸èƒ½å° '%s' å‘¼å« stat" - -#: read-cache.c -#, c-format msgid "unable to open git dir: %s" msgstr "ä¸èƒ½é–‹å•Ÿ git 目錄:%s" @@ -23244,17 +23511,12 @@ msgstr "'%s' å·²å˜åœ¨ï¼Œç„¡æ³•建立 '%s'" msgid "cannot process '%s' and '%s' at the same time" msgstr "ç„¡æ³•åŒæ™‚è™•ç† '%s' å’Œ '%s'" -#: refs/files-backend.c -#, c-format -msgid "could not remove reference %s" -msgstr "無法刪除引用 %s" - -#: refs/files-backend.c refs/packed-backend.c +#: refs.c #, c-format msgid "could not delete reference %s: %s" msgstr "無法刪除引用 %s:%s" -#: refs/files-backend.c refs/packed-backend.c +#: refs.c #, c-format msgid "could not delete references: %s" msgstr "無法刪除引用:%s" @@ -23928,8 +24190,16 @@ msgid "only download metadata for the branch that will be checked out" msgstr "åªä¸‹è¼‰æœƒç°½å‡ºçš„分支ä¸ä»‹è³‡æ–™" #: scalar.c -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "scalar clone [<options>] [--] <repo> [<dir>]" +msgid "create repository within 'src' directory" +msgstr "在 “src†目錄建立版本庫" + +#: scalar.c +msgid "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" +msgstr "" +"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" +"\t[--[no-]src] <url> [<enlistment>]" #: scalar.c #, c-format @@ -23995,13 +24265,32 @@ msgstr "ç„¡æ³•ç§»é™¤éŽæ™‚çš„ scalar.repo “%sâ€" #: scalar.c #, c-format -msgid "removing stale scalar.repo '%s'" -msgstr "æ£åœ¨ç§»é™¤éŽæ™‚çš„ scalar.repo “%sâ€" +msgid "removed stale scalar.repo '%s'" +msgstr "å·²ç§»é™¤éŽæ™‚çš„ scalar.repo “%sâ€" #: scalar.c #, c-format -msgid "git repository gone in '%s'" -msgstr "git 版本庫在「%sã€éºå¤±" +msgid "repository at '%s' has different owner" +msgstr "使–¼ “%s†的版本庫有ä¸åŒçš„æ“æœ‰è€…" + +#: scalar.c +#, c-format +msgid "repository at '%s' has a format issue" +msgstr "使–¼ “%sâ€ çš„ç‰ˆæœ¬åº«æœ‰æ ¼å¼å•題" + +#: scalar.c +#, c-format +msgid "repository not found in '%s'" +msgstr "版本庫ä¸åœ¨ “%sâ€" + +#: scalar.c +#, c-format +msgid "" +"to unregister this repository from Scalar, run\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" +msgstr "" +"如果è¦å¾ž Scalar 解除這個版本庫的註冊,請執行\n" +"\tgit config --global --unset --fixed-value scalar.repo \"%s\"" #: scalar.c msgid "" @@ -24385,7 +24674,7 @@ msgstr "無效的作者身分 '%s'" msgid "corrupt author: missing date information" msgstr "作者資訊æå£žï¼šç¼ºå°‘日期資訊" -#: sequencer.c t/helper/test-fast-rebase.c +#: sequencer.c #, c-format msgid "could not update %s" msgstr "ä¸èƒ½æ›´æ–° %s" @@ -24482,11 +24771,6 @@ msgstr "%s:ä¸èƒ½è§£æžçˆ¶æäº¤ %s" #: sequencer.c #, c-format -msgid "could not rename '%s' to '%s'" -msgstr "ä¸èƒ½å°‡ '%s' 釿–°å‘½å為 '%s'" - -#: sequencer.c -#, c-format msgid "could not revert %s... %s" msgstr "ä¸èƒ½é‚„原 %s... %s" @@ -24882,6 +25166,10 @@ msgid "Autostash exists; creating a new stash entry." msgstr "已有自動貯å˜ï¼›å»ºç«‹æ–°è²¯å˜é …目。" #: sequencer.c +msgid "autostash reference is a symref" +msgstr "autostash 引用是符號引用" + +#: sequencer.c msgid "could not detach HEAD" msgstr "ä¸èƒ½åˆ†é›¢é–‹é 指標" @@ -24917,13 +25205,13 @@ msgstr "" #: sequencer.c #, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "æ£åœ¨é‡å®šåŸºåº• (%d/%d)%s" +msgid "Stopped at %s... %.*s\n" +msgstr "åœæ¢åœ¨ %s... %.*s\n" #: sequencer.c #, c-format -msgid "Stopped at %s... %.*s\n" -msgstr "åœæ¢åœ¨ %s... %.*s\n" +msgid "Rebasing (%d/%d)%s" +msgstr "æ£åœ¨é‡å®šåŸºåº• (%d/%d)%s" #: sequencer.c #, c-format @@ -25255,6 +25543,11 @@ msgstr "無效的åˆå§‹åˆ†æ”¯å稱:'%s'" #: setup.c #, c-format +msgid "re-init: ignored --initial-branch=%s" +msgstr "re-init: 忽略 --initial-branch=%s" + +#: setup.c +#, c-format msgid "unable to handle file type %d" msgstr "ä¸èƒ½è™•ç† %d 類型的檔案" @@ -25268,14 +25561,14 @@ msgid "attempt to reinitialize repository with different hash" msgstr "嘗試以ä¸åŒçš„é›œæ¹Šå€¼é‡æ–°åˆå§‹åŒ–版本庫" #: setup.c -#, c-format -msgid "%s already exists" -msgstr "%s 已經å˜åœ¨" +msgid "" +"attempt to reinitialize repository with different reference storage format" +msgstr "嘗試以ä¸åŒçš„å¼•ç”¨å„²å˜æ ¼å¼é‡æ–°åˆå§‹åŒ–版本庫" #: setup.c #, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "re-init: 忽略 --initial-branch=%s" +msgid "%s already exists" +msgstr "%s 已經å˜åœ¨" #: setup.c #, c-format @@ -25591,14 +25884,6 @@ msgstr "æ¯æ¬¡è¿ä»£å‰æ¸…é™¤å¿«å–æ¨¹ç‹€ç‰©ä»¶" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "åœ¨å¿«å–æ¨¹ç‹€ç‰©ä»¶ä¸ï¼Œè¦ä½¿å¤±æ•ˆçš„é …ç›®æ•¸é‡ï¼ˆé è¨å€¼ç‚º 0)" -#: t/helper/test-fast-rebase.c -msgid "unhandled options" -msgstr "未處ç†é¸é …" - -#: t/helper/test-fast-rebase.c -msgid "error preparing revisions" -msgstr "準備修訂版本時發生錯誤" - #: t/helper/test-reach.c #, c-format msgid "commit %s is not marked reachable" @@ -25792,10 +26077,6 @@ msgstr "å”å®šä¸æ”¯æ´è¨å®šé 端æœå‹™è·¯å¾‘" msgid "invalid remote service path" msgstr "無效的é 端æœå‹™è·¯å¾‘" -#: transport-helper.c transport.c -msgid "operation not supported by protocol" -msgstr "å”å®šä¸æ”¯æ´è©²å‹•作" - #: transport-helper.c #, c-format msgid "can't connect to subservice %s" @@ -25961,11 +26242,6 @@ msgstr "å”定 v2 的支æ´å°šæœªå¯¦ç¾" #: transport.c #, c-format -msgid "unknown value for config '%s': %s" -msgstr "è¨å®š '%s' çš„å–值未知:%s" - -#: transport.c -#, c-format msgid "transport '%s' not allowed" msgstr "傳輸 '%s' ä¸å…許" @@ -26023,6 +26299,10 @@ msgstr "通訊å”å®šä¸æ”¯æ´ bundle-uri 動作" msgid "could not retrieve server-advertised bundle-uri list" msgstr "無法å–得伺æœå™¨å…¬ä½ˆçš„ bundle-uri 清單" +#: transport.c +msgid "operation not supported by protocol" +msgstr "å”å®šä¸æ”¯æ´è©²å‹•作" + #: tree-walk.c msgid "too-short tree object" msgstr "太çŸçš„æ¨¹ç‹€ç‰©ä»¶" @@ -26475,6 +26755,10 @@ msgstr "ä¸èƒ½å˜å– '%s'" msgid "unable to get current working directory" msgstr "ä¸èƒ½å–å¾—ç›®å‰å·¥ä½œç›®éŒ„" +#: wrapper.c +msgid "unable to get random bytes" +msgstr "無法å–得隨機ä½å…ƒçµ„" + #: wt-status.c msgid "Unmerged paths:" msgstr "未åˆä½µçš„路徑:" @@ -27047,6 +27331,11 @@ msgstr "å¦å¤–,您的索引ä¸åŒ…嫿œªæäº¤çš„變更。" msgid "cannot %s: Your index contains uncommitted changes." msgstr "ä¸èƒ½%s:您的索引ä¸åŒ…嫿œªæäº¤çš„變更。" +#: xdiff-interface.c +#, c-format +msgid "unknown style '%s' given for '%s'" +msgstr "給予「%2$sã€çš„「%1$sã€æ¨£å¼æœªçŸ¥" + #: git-merge-octopus.sh git-merge-resolve.sh msgid "" "Error: Your local changes to the following files would be overwritten by " @@ -27263,13 +27552,13 @@ msgstr "" #: git-send-email.perl #, perl-format -msgid "Failed to open %s: %s" -msgstr "無法開啟 %s: %s" +msgid "Failed to open %s.final: %s" +msgstr "無法開啟 %s.final: %s" #: git-send-email.perl #, perl-format -msgid "Failed to open %s.final: %s" -msgstr "無法開啟 %s.final: %s" +msgid "Failed to open %s: %s" +msgstr "無法開啟 %s: %s" #: git-send-email.perl msgid "Summary email is empty, skipping it\n" @@ -27504,516 +27793,54 @@ msgstr "ç•¥éŽ %s å«å‚™ä»½å¾Œç¶´ '%s'。\n" msgid "Do you really want to send %s? [y|N]: " msgstr "您真的è¦å‚³é€ %s?[y|N]: " -#, c-format -#~ msgid "It is not possible to %s because you have unmerged files." -#~ msgstr "無法 %s,有未åˆä½µçš„æª”案。" - -#~ msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" -#~ msgstr "ä¸å‘ git-mailsplit 傳入 --keep-cr 標記,無視 am.keepcr çš„è¨å®š" - -#~ 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 "" -#~ "æ›´æ–°è¢«æ‹’ï¼Œå› ç‚ºé 端追蹤分支的最新指é‡ç¹¼ä¸Šæ¬¡ç°½å‡ºå¾Œæœ‰æ›´æ–°ã€‚\n" -#~ "您å¯èƒ½æœƒå¸Œæœ›å…ˆå°‡é€™äº›è®Šæ›´æ•´åˆè‡³æœ¬åœ°ï¼ˆä¾‹å¦‚:‘git pull …’)\n" -#~ "最後æ‰å¼·åˆ¶æ›´æ–°ã€‚\n" - -#~ msgid "or do not fetch any tag at all (--no-tags)" -#~ msgstr "æˆ–ä¸æŠ“å–任何標籤(--no-tags)" - -#~ msgid "current working directory is untracked" -#~ msgstr "尚未追蹤目å‰çš„工作目錄" - -#~ msgid "cannot use --contents with final commit object name" -#~ msgstr "無法將 --contents 與最終的æäº¤ç‰©ä»¶å稱共用" - -#~ msgid "git bisect--helper --bisect-state (bad|new) [<rev>]" -#~ msgstr "git bisect--helper --bisect-state (bad|new) [<rev>]" - -#~ msgid "won't bisect on cg-seek'ed tree" -#~ msgstr "䏿œƒåœ¨åšäº† cg-seek 的樹狀物件上進行二分æœå°‹" - -#~ msgid "--bisect-terms requires 0 or 1 argument" -#~ msgstr "--bisect-terms éœ€è¦ 0 或 1 個引數" - -#~ msgid "--bisect-next requires 0 arguments" -#~ msgstr "--bisect-next éœ€è¦ 0 個引數" - -#~ msgid "--bisect-log requires 0 arguments" -#~ msgstr "--bisect-log éœ€è¦ 0 個引數" - -#~ msgid "git env--helper --type=[bool|ulong] <options> <env-var>" -#~ msgstr "git env--helper --type=[bool|ulong] <é¸é …> <環境變數>" - -#~ msgid "default for git_env_*(...) to fall back on" -#~ msgstr "git_env_*(...) çš„é è¨å€¼" - -#~ msgid "be quiet only use git_env_*() value as exit code" -#~ msgstr "å®‰éœæ¨¡å¼ï¼Œåªä½¿ç”¨ git_env_*() 的值作為離開碼" - -#, c-format -#~ msgid "" -#~ "option `--default' expects a boolean value with `--type=bool`, not `%s`" -#~ msgstr "é¸é …「--defaultã€é 期收到「--type=boolã€çš„布林值,而éžã€Œ%sã€" - -#, c-format -#~ msgid "" -#~ "option `--default' expects an unsigned long value with `--type=ulong`, " -#~ "not `%s`" -#~ msgstr "" -#~ "é¸é …「--defaultã€é 期收到「--type=ulongã€çš„無號 long 數值,而éžã€Œ%sã€" - -#~ msgid "please commit or stash them." -#~ msgstr "è«‹æäº¤æˆ–貯å˜å®ƒå€‘。" - -#, c-format -#~ msgid "Unknown mode: %s" -#~ msgstr "未知模å¼ï¼š%s" - -#, c-format -#~ msgid "%s doesn't support --super-prefix" -#~ msgstr "%s 䏿”¯æ´ --super-prefix" - -#, c-format -#~ msgid "no prefix given for --super-prefix\n" -#~ msgstr "沒有為 --super-prefix æä¾›å‰ç¶´\n" - -#, c-format -#~ msgid "failed to read object %s" -#~ msgstr "讀å–物件 %s 失敗" - -#~ msgid "file write error" -#~ msgstr "檔案寫錯誤" - -#~ msgid "corrupt commit" -#~ msgstr "æå£žçš„æäº¤" - -#~ msgid "corrupt tag" -#~ msgstr "æå£žçš„æ¨™ç±¤" - -#, c-format -#~ msgid "%%(objecttype) does not take arguments" -#~ msgstr "%%(objecttype) ä¸å¸¶åƒæ•¸" - -#, c-format -#~ msgid "%%(deltabase) does not take arguments" -#~ msgstr "%%(deltabase) ä¸å¸¶åƒæ•¸" - -#, c-format -#~ msgid "%%(body) does not take arguments" -#~ msgstr "%%(body) ä¸å¸¶åƒæ•¸" - -#, c-format -#~ msgid "unrecognized email option: %s" -#~ msgstr "無法è˜åˆ¥çš„ email é¸é …:%s" - -#~ msgid "could not lock HEAD" -#~ msgstr "ä¸èƒ½éŽ–å®š HEAD" - -#, 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 "" -#~ "耗費了 %.2f 秒以枚舉未追蹤的檔案。'status -uno' 也許能æé«˜é€Ÿåº¦ï¼Œ\n" -#~ "但您需è¦å°å¿ƒä¸è¦å¿˜äº†æ–°å¢žæ–°æª”案(åƒè¦‹ 'git help status')。" - -#, perl-format -#~ msgid "%12s %12s %s" -#~ msgstr "%12s %12s %s" - -#, perl-format -#~ msgid "touched %d path\n" -#~ msgid_plural "touched %d paths\n" -#~ msgstr[0] "建立了 %d 個路徑\n" - -#~ msgid "" -#~ "If the patch applies cleanly, the edited hunk will immediately be\n" -#~ "marked for staging." -#~ msgstr "如果修補檔能完全套用,編輯å€å¡Šå°‡ç«‹å³æ¨™è¨˜ç‚ºæš«å˜ã€‚" - -#~ msgid "" -#~ "If the patch applies cleanly, the edited hunk will immediately be\n" -#~ "marked for stashing." -#~ msgstr "如果修補檔能完全套用,編輯å€å¡Šå°‡ç«‹å³æ¨™è¨˜ç‚ºè²¯å˜ã€‚" - -#~ msgid "" -#~ "If the patch applies cleanly, the edited hunk will immediately be\n" -#~ "marked for unstaging." -#~ msgstr "如果修補檔能完全套用,編輯å€å¡Šå°‡ç«‹å³æ¨™è¨˜ç‚ºæœªæš«å˜ã€‚" - -#~ msgid "" -#~ "If the patch applies cleanly, the edited hunk will immediately be\n" -#~ "marked for applying." -#~ msgstr "如果修補檔能完全套用,編輯å€å¡Šå°‡ç«‹å³æ¨™è¨˜ç‚ºå¥—用。" - -#~ msgid "" -#~ "If the patch applies cleanly, the edited hunk will immediately be\n" -#~ "marked for discarding." -#~ msgstr "å¦‚æžœä¿®è£œæª”èƒ½å®Œå…¨å¥—ç”¨ï¼Œç·¨è¼¯å¡Šå°‡ç«‹å³æ¨™è¨˜ç‚ºæ¨æ£„。" - -#, perl-format -#~ msgid "failed to open hunk edit file for writing: %s" -#~ msgstr "為寫入開啟å€å¡Šç·¨è¼¯æª”案失敗:%s" - -#, 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 "" -#~ "---\n" -#~ "è¦åˆªé™¤ '%s' 開始的行,使其æˆç‚º ' ' 開始的行(上下文)。\n" -#~ "è¦åˆªé™¤ '%s' 開始的行,刪除它們。\n" -#~ "以 %s 開始的行將被刪除。\n" - -#, perl-format -#~ msgid "failed to open hunk edit file for reading: %s" -#~ msgstr "無法讀å–å€å¡Šç·¨è¼¯æª”案:%s" - -#~ 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 "" -#~ "y - æš«å˜æ¤å€å¡Š\n" -#~ "n - ä¸è¦æš«å˜æ¤å€å¡Š\n" -#~ "q - é›¢é–‹ã€‚ä¸æš«å˜æ¤å€å¡ŠåŠå¾Œé¢çš„全部å€å¡Š\n" -#~ "a - æš«å˜æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š\n" -#~ "d - 䏿š«å˜æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š" - -#~ 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 "" -#~ "y - è²¯å˜æ¤å€å¡Š\n" -#~ "n - ä¸è¦è²¯å˜æ¤å€å¡Š\n" -#~ "q - 離開。ä¸è²¯å˜æ¤å€å¡ŠåŠå¾Œé¢çš„全部å€å¡Š\n" -#~ "a - è²¯å˜æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š\n" -#~ "d - ä¸è²¯å˜æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š" - -#~ 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 "" -#~ "y - 䏿š«å˜æ¤å€å¡Š\n" -#~ "n - ä¸è¦ä¸æš«å˜æ¤å€å¡Š\n" -#~ "q - 離開。ä¸è¦ä¸æš«å˜æ¤å€å¡ŠåŠå¾Œé¢çš„全部å€å¡Š\n" -#~ "a - 䏿š«å˜æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š\n" -#~ "d - ä¸è¦ä¸æš«å˜æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š" - -#~ 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 "" -#~ "y - 在索引ä¸å¥—用æ¤å€å¡Š\n" -#~ "n - ä¸è¦åœ¨ç´¢å¼•ä¸å¥—用æ¤å€å¡Š\n" -#~ "q - 離開。ä¸è¦å¥—用æ¤å€å¡ŠåŠå¾Œé¢çš„全部å€å¡Š\n" -#~ "a - 套用æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š\n" -#~ "d - ä¸è¦å¥—用æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š" +#~ msgid "-x and -X cannot be used together" +#~ msgstr "-x å’Œ -X ä¸èƒ½åŒæ™‚使用" #~ 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" +#~ "--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-" +#~ "exclude" #~ msgstr "" -#~ "y - 在工作å€ä¸æ¨æ£„æ¤å€å¡Š\n" -#~ "n - ä¸è¦åœ¨å·¥ä½œå€ä¸æ¨æ£„æ¤å€å¡Š\n" -#~ "q - 離開。ä¸è¦æ¨æ£„æ¤å€å¡ŠåŠå¾Œé¢çš„全部å€å¡Š\n" -#~ "a - æ¨æ£„æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š\n" -#~ "d - ä¸è¦æ¨æ£„æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š" - -#~ 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 "" -#~ "y - 在索引和工作å€ä¸æ¨æ£„æ¤å€å¡Š\n" -#~ "n - ä¸è¦åœ¨ç´¢å¼•和工作å€ä¸æ¨æ£„æ¤å€å¡Š\n" -#~ "q - 離開。ä¸è¦æ¨æ£„æ¤å€å¡ŠåŠå¾Œé¢çš„全部å€å¡Š\n" -#~ "a - æ¨æ£„æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š\n" -#~ "d - ä¸è¦æ¨æ£„æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š" - -#~ 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 "" -#~ "y - 在索引和工作å€ä¸å¥—用æ¤å€å¡Š\n" -#~ "n - ä¸è¦åœ¨ç´¢å¼•和工作å€ä¸å¥—用æ¤å€å¡Š\n" -#~ "q - 離開。ä¸è¦å¥—用æ¤å€å¡ŠåŠå¾Œé¢çš„全部å€å¡Š\n" -#~ "a - 套用æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š\n" -#~ "d - ä¸è¦å¥—用æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š" - -#~ 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 "" -#~ "y - 在工作å€ä¸å¥—用æ¤å€å¡Š\n" -#~ "n - ä¸è¦åœ¨å·¥ä½œå€ä¸å¥—用æ¤å€å¡Š\n" -#~ "q - 離開。ä¸è¦å¥—用æ¤å€å¡ŠåŠå¾Œé¢çš„全部å€å¡Š\n" -#~ "a - 套用æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š\n" -#~ "d - ä¸è¦å¥—用æ¤å€å¡Šå’Œæœ¬æª”案ä¸å¾Œé¢çš„全部å€å¡Š" - -#~ 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 "" -#~ "g - 鏿“‡è·³è½‰åˆ°ä¸€å€‹å€å¡Š\n" -#~ "/ - 尋找和æä¾›å¸¸è¦è¡¨ç¤ºå¼ç¬¦åˆçš„å€å¡Š\n" -#~ "j - ç¶æŒæ¤å€å¡Šæœªæ±ºç‹€æ…‹ï¼Œæª¢è¦–下一個未決定å€å¡Š\n" -#~ "J - ç¶æŒæ¤å€å¡Šæœªæ±ºç‹€æ…‹ï¼Œæª¢è¦–下一個å€å¡Š\n" -#~ "k - ç¶æŒæ¤å€å¡Šæœªæ±ºç‹€æ…‹ï¼Œæª¢è¦–上一個未決定å€å¡Š\n" -#~ "K - ç¶æŒæ¤å€å¡Šæœªæ±ºç‹€æ…‹ï¼Œæª¢è¦–上一個å€å¡Š\n" -#~ "s - 分割目å‰å€å¡Šç‚ºæ›´å°çš„å€å¡Š\n" -#~ "e - 手動編輯目å‰å€å¡Š\n" -#~ "? - 顯示說明\n" - -#~ msgid "The selected hunks do not apply to the index!\n" -#~ msgstr "é¸å–å€å¡Šä¸èƒ½å¥—用到索引ï¼\n" - -#, perl-format -#~ msgid "ignoring unmerged: %s\n" -#~ msgstr "忽略未套用的:%s\n" +#~ "--bundle-uri 與 --depthã€--shallow-since å’Œ --shallow-exclude ä¸ç›¸å®¹" -#~ msgid "No other hunks to goto\n" -#~ msgstr "沒有其它å¯ä¾›è·³è½‰çš„å€å¡Š\n" - -#, perl-format -#~ msgid "Invalid number: '%s'\n" -#~ msgstr "無效數å—:'%s'\n" - -#, perl-format -#~ msgid "Sorry, only %d hunk available.\n" -#~ msgid_plural "Sorry, only %d hunks available.\n" -#~ msgstr[0] "å°ä¸èµ·ï¼Œåªæœ‰ %d 個å¯ç”¨å€å¡Šã€‚\n" - -#~ msgid "No other hunks to search\n" -#~ msgstr "沒有其它å¯ä¾›å°‹æ‰¾çš„å€å¡Š\n" - -#, perl-format -#~ msgid "Malformed search regexp %s: %s\n" -#~ msgstr "錯誤的常è¦è¡¨ç¤ºå¼ %s:%s\n" - -#~ msgid "No hunk matches the given pattern\n" -#~ msgstr "沒有和æä¾›æ¨¡å¼ç›¸ç¬¦åˆçš„å€å¡Š\n" - -#~ msgid "No previous hunk\n" -#~ msgstr "沒有上一個å€å¡Š\n" - -#~ msgid "No next hunk\n" -#~ msgstr "沒有下一個å€å¡Š\n" - -#~ msgid "Sorry, cannot split this hunk\n" -#~ msgstr "å°ä¸èµ·ï¼Œä¸èƒ½åˆ†å‰²é€™å€‹å€å¡Š\n" - -#, perl-format -#~ msgid "Split into %d hunk.\n" -#~ msgid_plural "Split into %d hunks.\n" -#~ msgstr[0] "分割為 %d 塊。\n" - -#~ msgid "Sorry, cannot edit this hunk\n" -#~ msgstr "å°ä¸èµ·ï¼Œä¸èƒ½ç·¨è¼¯é€™å€‹å€å¡Š\n" +#~ msgid "--merge-base is incompatible with --stdin" +#~ msgstr "--merge-base 與 --stdin ä¸ç›¸å®¹" #~ 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 "" -#~ "status - 顯示å«è®Šæ›´çš„路徑\n" -#~ "update - 新增工作å€ç‹€æ…‹è‡³æš«å˜åˆ—表\n" -#~ "revert - 還原修改的暫å˜é›†è‡³ HEAD 版本\n" -#~ "patch - 挑é¸å€å¡Šä¸¦ä¸”æœ‰é¸æ“‡åœ°æ›´æ–°\n" -#~ "diff - 顯示 HEAD 和索引間差異\n" -#~ "add untracked - 新增未追蹤檔案的內容至暫å˜åˆ—表\n" +#~ "apply options are incompatible with rebase.autoSquash. Consider adding --" +#~ "no-autosquash" +#~ msgstr "apply é¸é …與 rebase.autoSquash ä¸ç›¸å®¹ã€‚è«‹è€ƒæ…®åŠ ä¸Š --no-autosquash" -#~ msgid "missing --" -#~ msgstr "缺少 --" +#~ msgid "--exclude-hidden cannot be used together with --branches" +#~ msgstr "--exclude-hidden 無法與 --branches åŒæ™‚使用" -#, perl-format -#~ msgid "unknown --patch mode: %s" -#~ msgstr "未知的 --patch 模å¼ï¼š%s" +#~ msgid "--exclude-hidden cannot be used together with --tags" +#~ msgstr "--exclude-hidden 無法與 --tags åŒæ™‚使用" -#, perl-format -#~ msgid "invalid argument %s, expecting --" -#~ msgstr "ç„¡æ•ˆçš„åƒæ•¸ %s,期望是 --" +#~ msgid "--exclude-hidden cannot be used together with --remotes" +#~ msgstr "--exclude-hidden 無法與 --remotes åŒæ™‚使用" #, c-format -#~ msgid "unable to normalize object directory: %s" -#~ msgstr "無法è¦ç¯„化物件目錄: %s" - -#~ msgid "reset the bisection state" -#~ msgstr "清除二分æœå°‹ç‹€æ…‹" - -#~ msgid "check whether bad or good terms exist" -#~ msgstr "檢查壞的或好的術語是å¦å˜åœ¨" - -#~ msgid "print out the bisect terms" -#~ msgstr "列å°äºŒåˆ†æœå°‹è¡“語" - -#~ msgid "start the bisect session" -#~ msgstr "啟動二分æœå°‹éŽç¨‹" - -#~ msgid "find the next bisection commit" -#~ msgstr "尋找下一個二分æœå°‹æäº¤" - -#~ msgid "mark the state of ref (or refs)" -#~ msgstr "標記 ref (或 refs) 的狀態" - -#~ msgid "list the bisection steps so far" -#~ msgstr "列出迄今的二分æœå°‹æ¥é©Ÿ" - -#~ msgid "replay the bisection process from the given file" -#~ msgstr "å¾žæŒ‡å®šæª”æ¡ˆé‡æ”¾äºŒåˆ†æœå°‹éŽç¨‹" - -#~ msgid "skip some commits for checkout" -#~ msgstr "ç•¥éŽè¦ç°½å‡ºçš„部分æäº¤" - -#~ msgid "visualize the bisection" -#~ msgstr "視覺化二分æœå°‹éŽç¨‹" - -#~ msgid "use <cmd>... to automatically bisect" -#~ msgstr "使用 <cmd>... 自動進行二分æœå°‹" - -#~ msgid "no log for BISECT_WRITE" -#~ msgstr "BISECT_WRITE 無日誌" - -#~ msgid "Couldn't look up commit object for HEAD" -#~ msgstr "無法查詢 HEAD 指å‘çš„æäº¤ç‰©ä»¶" - -#~ msgid "git bundle create [<options>] <file> <git-rev-list args>" -#~ msgstr "git bundle create [<é¸é …>] <檔案> <git-rev-list åƒæ•¸>" +#~ msgid "only one of '%s', '%s' or '%s' can be given" +#~ msgstr "åªèƒ½å‚³å…¥ “%sâ€ã€â€œ%s†或 “%sâ€" #, c-format -#~ msgid "options '%s' and '%s %s' cannot be used together" -#~ msgstr "「%sã€å’Œã€Œ%s %sã€é¸é …ä¸å¾—åŒæ™‚使用" - -#~ msgid "git commit [<options>] [--] <pathspec>..." -#~ msgstr "git commit [<é¸é …>] [--] <è·¯å¾‘è¦æ ¼>..." - -#~ msgid "git fsck [<options>] [<object>...]" -#~ msgstr "git fsck [<é¸é …>] [<物件>...]" - -#~ msgid "git fsmonitor--daemon stop" -#~ msgstr "git fsmonitor--daemon stop" - -#~ msgid "git fsmonitor--daemon status" -#~ msgstr "git fsmonitor--daemon status" - -#~ msgid "failed to run 'git config'" -#~ msgstr "無法執行 ‘git config’" +#~ msgid "'%s' and '%s' cannot be used together" +#~ msgstr "ç„¡æ³•åŒæ™‚使用 “%s†和 “%sâ€" #, c-format -#~ msgid "could not get 'onto': '%s'" -#~ msgstr "無法å–å¾— 'onto':'%s'" +#~ msgid "options '%s', and '%s' cannot be used together" +#~ msgstr "ç„¡æ³•åŒæ™‚使用 “%s†和 “%s†é¸é …" -#~ msgid "Could not resolve HEAD to a revision" -#~ msgstr "無法將 HEAD è§£æžç‚ºä¸€å€‹ç‰ˆæœ¬" +#~ msgid "<commit-ish>" +#~ msgstr "<æäº¤æŒ‡ç¤ºå…ƒ>" #, c-format -#~ msgid "missing required file: %s" -#~ msgstr "ç¼ºå°‘å¿…è¦æª”案:%s" - -#~ msgid "git revert [<options>] <commit-ish>..." -#~ msgstr "git revert [<é¸é …>] <æäº¤è™Ÿ>..." - -#~ msgid "git revert <subcommand>" -#~ msgstr "git revert <åæŒ‡ä»¤>" - -#~ msgid "git cherry-pick [<options>] <commit-ish>..." -#~ msgstr "git cherry-pick [<é¸é …>] <æäº¤è™Ÿ>..." - -#~ msgid "git cherry-pick <subcommand>" -#~ msgstr "git cherry-pick <åæŒ‡ä»¤>" - -#~ msgid "git rm [<options>] [--] <file>..." -#~ msgstr "git rm [<é¸é …>] [--] <檔案>..." - -#~ msgid "using --group=trailer with stdin is not supported" -#~ msgstr "䏿”¯æ´åœ¨æ¨™æº–輸入使用 --group=trailer" - -#~ msgid "git stash show [<options>] [<stash>]" -#~ msgstr "git stash show [<é¸é …>] [<stash>]" - -#~ msgid "git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]" -#~ msgstr "git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]" - -#~ msgid "" -#~ "git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n" -#~ " [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n" -#~ " [--] [<pathspec>...]]" -#~ msgstr "" -#~ "git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n" -#~ " [-u|--include-untracked] [-a|--all] [-m|--message <消æ¯>]\n" -#~ " [--] [<è·¯å¾‘è¦æ ¼>...]]" - -#~ msgid "" -#~ "git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n" -#~ " [-u|--include-untracked] [-a|--all] [<message>]" -#~ msgstr "" -#~ "git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n" -#~ " [-u|--include-untracked] [-a|--all] [<消æ¯>]" - -#~ msgid "path into the working tree" -#~ msgstr "到工作å€çš„路徑" - -#~ msgid "recurse into submodules" -#~ msgstr "åœ¨åæ¨¡çµ„ä¸éžè¿´" - -#~ msgid "check if it is safe to write to the .gitmodules file" -#~ msgstr "檢查寫入 .gitmodules 檔案是å¦å®‰å…¨" - -#~ msgid "unset the config in the .gitmodules file" -#~ msgstr "å–æ¶ˆ .gitmodules 檔案ä¸çš„è¨å®š" - -#~ msgid "git submodule--helper config --unset <name>" -#~ msgstr "git submodule--helper config --unset <å稱>" +#~ msgid "%s is incompatible with %s" +#~ msgstr "%s 與 %s ä¸ç›¸å®¹" #, c-format -#~ msgid "'%s' is not a valid submodule--helper subcommand" -#~ msgstr "'%s' 䏿˜¯ä¸€å€‹æœ‰æ•ˆçš„ submodule--helper åæŒ‡ä»¤" - -#~ msgid "git upload-pack [<options>] <dir>" -#~ msgstr "git upload-pack [<é¸é …>] <目錄>" - -#~ msgid "git worktree add [<options>] <path> [<commit-ish>]" -#~ msgstr "git worktree add [<é¸é …>] <路徑> [<æäº¤>]" +#~ msgid "could not remove reference %s" +#~ msgstr "無法刪除引用 %s" -#~ msgid "git worktree lock [<options>] <path>" -#~ msgstr "git worktree lock [<é¸é …>] <路徑>" +#~ msgid "unhandled options" +#~ msgstr "未處ç†é¸é …" diff --git a/protocol-caps.c b/protocol-caps.c index 808a68c974..75f4cbb0a7 100644 --- a/protocol-caps.c +++ b/protocol-caps.c @@ -3,7 +3,6 @@ #include "gettext.h" #include "hex.h" #include "pkt-line.h" -#include "strvec.h" #include "hash-ll.h" #include "hex.h" #include "object.h" diff --git a/protocol.h b/protocol.h index de66bf80f8..1e574bbd80 100644 --- a/protocol.h +++ b/protocol.h @@ -18,7 +18,7 @@ * with Linus Torvalds <torvalds@osdl.org> as the point of * contact. September 2005. * - * See http://www.iana.org/assignments/port-numbers + * See https://www.iana.org/assignments/port-numbers */ #define DEFAULT_GIT_PORT 9418 diff --git a/reachable.c b/reachable.c index 0ce8f83e56..3b85add243 100644 --- a/reachable.c +++ b/reachable.c @@ -2,7 +2,6 @@ #include "gettext.h" #include "hex.h" #include "refs.h" -#include "tag.h" #include "commit.h" #include "blob.h" #include "diff.h" @@ -18,6 +17,7 @@ #include "pack-mtimes.h" #include "config.h" #include "run-command.h" +#include "sequencer.h" struct connectivity_progress { struct progress *progress; @@ -31,6 +31,52 @@ static void update_progress(struct connectivity_progress *cp) display_progress(cp->progress, cp->count); } +static void add_one_file(const char *path, struct rev_info *revs) +{ + struct strbuf buf = STRBUF_INIT; + struct object_id oid; + struct object *object; + + if (!read_oneliner(&buf, path, READ_ONELINER_SKIP_IF_EMPTY)) { + strbuf_release(&buf); + return; + } + strbuf_trim(&buf); + if (!get_oid_hex(buf.buf, &oid)) { + object = parse_object_or_die(&oid, buf.buf); + add_pending_object(revs, object, ""); + } + strbuf_release(&buf); +} + +/* Mark objects recorded in rebase state files as reachable. */ +static void add_rebase_files(struct rev_info *revs) +{ + struct strbuf buf = STRBUF_INIT; + size_t len; + const char *path[] = { + "rebase-apply/autostash", + "rebase-apply/orig-head", + "rebase-merge/autostash", + "rebase-merge/orig-head", + }; + struct worktree **worktrees = get_worktrees(); + + for (struct worktree **wt = worktrees; *wt; wt++) { + strbuf_reset(&buf); + strbuf_addstr(&buf, get_worktree_git_dir(*wt)); + strbuf_complete(&buf, '/'); + len = buf.len; + for (size_t i = 0; i < ARRAY_SIZE(path); i++) { + strbuf_setlen(&buf, len); + strbuf_addstr(&buf, path[i]); + add_one_file(buf.buf, revs); + } + } + strbuf_release(&buf); + free_worktrees(worktrees); +} + static int add_one_ref(const char *path, const struct object_id *oid, int flag, void *cb_data) { @@ -323,6 +369,9 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog, head_ref(add_one_ref, revs); other_head_refs(add_one_ref, revs); + /* rebase autostash and orig-head */ + add_rebase_files(revs); + /* Add all reflog info */ if (mark_reflog) add_reflogs_to_pending(revs, 0); diff --git a/read-cache-ll.h b/read-cache-ll.h index 9a1a7edc5a..2a50a784f0 100644 --- a/read-cache-ll.h +++ b/read-cache-ll.h @@ -436,6 +436,14 @@ int match_stat_data_racy(const struct index_state *istate, void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, struct stat *st); +/* + * Fill members of st by members of sd enough to convince match_stat() + * to consider that they match. It should be usable as a replacement + * for lstat() for a tracked path that is known to be up-to-date via + * some out-of-line means (like fsmonitor). + */ +int fake_lstat(const struct cache_entry *ce, struct stat *st); + #define REFRESH_REALLY (1 << 0) /* ignore_valid */ #define REFRESH_UNMERGED (1 << 1) /* allow unmerged */ #define REFRESH_QUIET (1 << 2) /* be quiet about it */ diff --git a/read-cache.c b/read-cache.c index 080bd39713..f546cf7875 100644 --- a/read-cache.c +++ b/read-cache.c @@ -20,7 +20,6 @@ #include "oid-array.h" #include "tree.h" #include "commit.h" -#include "blob.h" #include "environment.h" #include "gettext.h" #include "mem-pool.h" @@ -31,7 +30,6 @@ #include "read-cache.h" #include "resolve-undo.h" #include "revision.h" -#include "run-command.h" #include "strbuf.h" #include "trace2.h" #include "varint.h" @@ -197,6 +195,33 @@ void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, st } } +static unsigned int st_mode_from_ce(const struct cache_entry *ce) +{ + extern int trust_executable_bit, has_symlinks; + + switch (ce->ce_mode & S_IFMT) { + case S_IFLNK: + return has_symlinks ? S_IFLNK : (S_IFREG | 0644); + case S_IFREG: + return (ce->ce_mode & (trust_executable_bit ? 0755 : 0644)) | S_IFREG; + case S_IFGITLINK: + return S_IFDIR | 0755; + case S_IFDIR: + return ce->ce_mode; + default: + BUG("unsupported ce_mode: %o", ce->ce_mode); + } +} + +int fake_lstat(const struct cache_entry *ce, struct stat *st) +{ + fake_lstat_data(&ce->ce_stat_data, st); + st->st_mode = st_mode_from_ce(ce); + + /* always succeed as lstat() replacement */ + return 0; +} + static int ce_compare_data(struct index_state *istate, const struct cache_entry *ce, struct stat *st) diff --git a/ref-filter.c b/ref-filter.c index e4d3510e28..0ec29f7385 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -22,16 +22,13 @@ #include "ref-filter.h" #include "revision.h" #include "utf8.h" -#include "version.h" #include "versioncmp.h" #include "trailer.h" #include "wt-status.h" #include "commit-slab.h" -#include "commit-graph.h" #include "commit-reach.h" #include "worktree.h" #include "hashmap.h" -#include "strvec.h" static struct ref_msg { const char *gone; @@ -1614,6 +1611,12 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam if (formatp) { formatp++; parse_date_format(formatp, &date_mode); + + /* + * If this is a sort field and a format was specified, we'll + * want to compare formatted date by string value. + */ + v->atom->type = FIELD_STR; } if (!eoemail) @@ -2212,7 +2215,7 @@ char *get_head_description(void) state.detached_from); } else if (state.bisect_in_progress) strbuf_addf(&desc, _("(no branch, bisect started on %s)"), - state.branch); + state.bisecting_from); else if (state.detached_from) { if (state.detached_at) strbuf_addf(&desc, _("(HEAD detached at %s)"), @@ -2508,17 +2511,12 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err) return 0; /* - * If it is a tag object, see if we use a value that derefs - * the object, and if we do grab the object it refers to. + * If it is a tag object, see if we use the peeled value. If we do, + * grab the peeled OID. */ - oi_deref.oid = *get_tagged_oid((struct tag *)obj); + if (need_tagged && peel_iterated_oid(&obj->oid, &oi_deref.oid)) + die("bad tag"); - /* - * NEEDSWORK: This derefs tag only once, which - * is good to deal with chains of trust, but - * is not consistent with what deref_tag() does - * which peels the onion to the core. - */ return get_object(ref, 1, &obj, &oi_deref, err); } @@ -2630,6 +2628,12 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter, each_ref_fn cb, void *cb_data) { + if (filter->kind == FILTER_REFS_KIND_MASK) { + /* In this case, we want to print all refs including root refs. */ + return refs_for_each_include_root_refs(get_main_ref_store(the_repository), + cb, cb_data); + } + if (!filter->match_as_path) { /* * in this case, the patterns are applied after @@ -2716,15 +2720,18 @@ static struct ref_array_item *new_ref_array_item(const char *refname, return ref; } +static void ref_array_append(struct ref_array *array, struct ref_array_item *ref) +{ + ALLOC_GROW(array->items, array->nr + 1, array->alloc); + array->items[array->nr++] = ref; +} + struct ref_array_item *ref_array_push(struct ref_array *array, const char *refname, const struct object_id *oid) { struct ref_array_item *ref = new_ref_array_item(refname, oid); - - ALLOC_GROW(array->items, array->nr + 1, array->alloc); - array->items[array->nr++] = ref; - + ref_array_append(array, ref); return ref; } @@ -2749,6 +2756,9 @@ static int ref_kind_from_refname(const char *refname) return ref_kind[i].kind; } + if (is_pseudoref(get_main_ref_store(the_repository), refname)) + return FILTER_REFS_PSEUDOREFS; + return FILTER_REFS_OTHERS; } @@ -2761,48 +2771,45 @@ static int filter_ref_kind(struct ref_filter *filter, const char *refname) return ref_kind_from_refname(refname); } -struct ref_filter_cbdata { - struct ref_array *array; - struct ref_filter *filter; - struct contains_cache contains_cache; - struct contains_cache no_contains_cache; -}; - -/* - * A call-back given to for_each_ref(). Filter refs and keep them for - * later object processing. - */ -static int ref_filter_handler(const char *refname, const struct object_id *oid, int flag, void *cb_data) +static struct ref_array_item *apply_ref_filter(const char *refname, const struct object_id *oid, + int flag, struct ref_filter *filter) { - struct ref_filter_cbdata *ref_cbdata = cb_data; - struct ref_filter *filter = ref_cbdata->filter; struct ref_array_item *ref; struct commit *commit = NULL; unsigned int kind; if (flag & REF_BAD_NAME) { warning(_("ignoring ref with broken name %s"), refname); - return 0; + return NULL; } if (flag & REF_ISBROKEN) { warning(_("ignoring broken ref %s"), refname); - return 0; + return NULL; } /* Obtain the current ref kind from filter_ref_kind() and ignore unwanted refs. */ kind = filter_ref_kind(filter, refname); - if (!(kind & filter->kind)) - return 0; + + /* + * Generally HEAD refs are printed with special description denoting a rebase, + * detached state and so forth. This is useful when only printing the HEAD ref + * But when it is being printed along with other pseudorefs, it makes sense to + * keep the formatting consistent. So we mask the type to act like a pseudoref. + */ + if (filter->kind == FILTER_REFS_KIND_MASK && kind == FILTER_REFS_DETACHED_HEAD) + kind = FILTER_REFS_PSEUDOREFS; + else if (!(kind & filter->kind)) + return NULL; if (!filter_pattern_match(filter, refname)) - return 0; + return NULL; if (filter_exclude_match(filter, refname)) - return 0; + return NULL; if (filter->points_at.nr && !match_points_at(&filter->points_at, oid, refname)) - return 0; + return NULL; /* * A merge filter is applied on refs pointing to commits. Hence @@ -2813,15 +2820,15 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid, filter->with_commit || filter->no_commit || filter->verbose) { commit = lookup_commit_reference_gently(the_repository, oid, 1); if (!commit) - return 0; + return NULL; /* We perform the filtering for the '--contains' option... */ if (filter->with_commit && - !commit_contains(filter, commit, filter->with_commit, &ref_cbdata->contains_cache)) - return 0; + !commit_contains(filter, commit, filter->with_commit, &filter->internal.contains_cache)) + return NULL; /* ...or for the `--no-contains' option */ if (filter->no_commit && - commit_contains(filter, commit, filter->no_commit, &ref_cbdata->no_contains_cache)) - return 0; + commit_contains(filter, commit, filter->no_commit, &filter->internal.no_contains_cache)) + return NULL; } /* @@ -2829,11 +2836,32 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid, * to do its job and the resulting list may yet to be pruned * by maxcount logic. */ - ref = ref_array_push(ref_cbdata->array, refname, oid); + ref = new_ref_array_item(refname, oid); ref->commit = commit; ref->flag = flag; ref->kind = kind; + return ref; +} + +struct ref_filter_cbdata { + struct ref_array *array; + struct ref_filter *filter; +}; + +/* + * A call-back given to for_each_ref(). Filter refs and keep them for + * later object processing. + */ +static int filter_one(const char *refname, const struct object_id *oid, int flag, void *cb_data) +{ + struct ref_filter_cbdata *ref_cbdata = cb_data; + struct ref_array_item *ref; + + ref = apply_ref_filter(refname, oid, flag, ref_cbdata->filter); + if (ref) + ref_array_append(ref_cbdata->array, ref); + return 0; } @@ -2851,6 +2879,49 @@ static void free_array_item(struct ref_array_item *item) free(item); } +struct ref_filter_and_format_cbdata { + struct ref_filter *filter; + struct ref_format *format; + + struct ref_filter_and_format_internal { + int count; + } internal; +}; + +static int filter_and_format_one(const char *refname, const struct object_id *oid, int flag, void *cb_data) +{ + struct ref_filter_and_format_cbdata *ref_cbdata = cb_data; + struct ref_array_item *ref; + struct strbuf output = STRBUF_INIT, err = STRBUF_INIT; + + ref = apply_ref_filter(refname, oid, flag, ref_cbdata->filter); + if (!ref) + return 0; + + if (format_ref_array_item(ref, ref_cbdata->format, &output, &err)) + die("%s", err.buf); + + if (output.len || !ref_cbdata->format->array_opts.omit_empty) { + fwrite(output.buf, 1, output.len, stdout); + putchar('\n'); + } + + strbuf_release(&output); + strbuf_release(&err); + free_array_item(ref); + + /* + * Increment the running count of refs that match the filter. If + * max_count is set and we've reached the max, stop the ref + * iteration by returning a nonzero value. + */ + if (ref_cbdata->format->array_opts.max_count && + ++ref_cbdata->internal.count >= ref_cbdata->format->array_opts.max_count) + return 1; + + return 0; +} + /* Free all memory allocated for ref_array */ void ref_array_clear(struct ref_array *array) { @@ -2969,28 +3040,14 @@ void filter_ahead_behind(struct repository *r, free(commits); } -/* - * API for filtering a set of refs. Based on the type of refs the user - * has requested, we iterate through those refs and apply filters - * as per the given ref_filter structure and finally store the - * filtered refs in the ref_array structure. - */ -int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type) +static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref_fn fn, void *cb_data) { - struct ref_filter_cbdata ref_cbdata; - int save_commit_buffer_orig; int ret = 0; - ref_cbdata.array = array; - ref_cbdata.filter = filter; - filter->kind = type & FILTER_REFS_KIND_MASK; - save_commit_buffer_orig = save_commit_buffer; - save_commit_buffer = 0; - - init_contains_cache(&ref_cbdata.contains_cache); - init_contains_cache(&ref_cbdata.no_contains_cache); + init_contains_cache(&filter->internal.contains_cache); + init_contains_cache(&filter->internal.no_contains_cache); /* Simple per-ref filtering */ if (!filter->kind) @@ -3003,19 +3060,48 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int * of filter_ref_kind(). */ if (filter->kind == FILTER_REFS_BRANCHES) - ret = for_each_fullref_in("refs/heads/", ref_filter_handler, &ref_cbdata); + ret = for_each_fullref_in("refs/heads/", fn, cb_data); else if (filter->kind == FILTER_REFS_REMOTES) - ret = for_each_fullref_in("refs/remotes/", ref_filter_handler, &ref_cbdata); + ret = for_each_fullref_in("refs/remotes/", fn, cb_data); else if (filter->kind == FILTER_REFS_TAGS) - ret = for_each_fullref_in("refs/tags/", ref_filter_handler, &ref_cbdata); - else if (filter->kind & FILTER_REFS_ALL) - ret = for_each_fullref_in_pattern(filter, ref_filter_handler, &ref_cbdata); - if (!ret && (filter->kind & FILTER_REFS_DETACHED_HEAD)) - head_ref(ref_filter_handler, &ref_cbdata); + ret = for_each_fullref_in("refs/tags/", fn, cb_data); + else if (filter->kind & FILTER_REFS_REGULAR) + ret = for_each_fullref_in_pattern(filter, fn, cb_data); + + /* + * When printing all ref types, HEAD is already included, + * so we don't want to print HEAD again. + */ + if (!ret && (filter->kind != FILTER_REFS_KIND_MASK) && + (filter->kind & FILTER_REFS_DETACHED_HEAD)) + head_ref(fn, cb_data); } - clear_contains_cache(&ref_cbdata.contains_cache); - clear_contains_cache(&ref_cbdata.no_contains_cache); + clear_contains_cache(&filter->internal.contains_cache); + clear_contains_cache(&filter->internal.no_contains_cache); + + return ret; +} + +/* + * API for filtering a set of refs. Based on the type of refs the user + * has requested, we iterate through those refs and apply filters + * as per the given ref_filter structure and finally store the + * filtered refs in the ref_array structure. + */ +int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type) +{ + struct ref_filter_cbdata ref_cbdata; + int save_commit_buffer_orig; + int ret = 0; + + ref_cbdata.array = array; + ref_cbdata.filter = filter; + + save_commit_buffer_orig = save_commit_buffer; + save_commit_buffer = 0; + + ret = do_filter_refs(filter, type, filter_one, &ref_cbdata); /* Filters that need revision walking */ reach_filter(array, &filter->reachable_from, INCLUDE_REACHED); @@ -3025,6 +3111,51 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int return ret; } +static inline int can_do_iterative_format(struct ref_filter *filter, + struct ref_sorting *sorting, + struct ref_format *format) +{ + /* + * Filtering & formatting results within a single ref iteration + * callback is not compatible with options that require + * post-processing a filtered ref_array. These include: + * - filtering on reachability + * - sorting the filtered results + * - including ahead-behind information in the formatted output + */ + return !(filter->reachable_from || + filter->unreachable_from || + sorting || + format->bases.nr); +} + +void filter_and_format_refs(struct ref_filter *filter, unsigned int type, + struct ref_sorting *sorting, + struct ref_format *format) +{ + if (can_do_iterative_format(filter, sorting, format)) { + int save_commit_buffer_orig; + struct ref_filter_and_format_cbdata ref_cbdata = { + .filter = filter, + .format = format, + }; + + save_commit_buffer_orig = save_commit_buffer; + save_commit_buffer = 0; + + do_filter_refs(filter, type, filter_and_format_one, &ref_cbdata); + + save_commit_buffer = save_commit_buffer_orig; + } else { + struct ref_array array = { 0 }; + filter_refs(&array, filter, type); + filter_ahead_behind(the_repository, format, &array); + ref_array_sort(sorting, &array); + print_formatted_ref_array(&array, format); + ref_array_clear(&array); + } +} + static int compare_detached_head(struct ref_array_item *a, struct ref_array_item *b) { if (!(a->kind ^ b->kind)) @@ -3142,7 +3273,8 @@ void ref_sorting_set_sort_flags_all(struct ref_sorting *sorting, void ref_array_sort(struct ref_sorting *sorting, struct ref_array *array) { - QSORT_S(array->items, array->nr, compare_refs, sorting); + if (sorting) + QSORT_S(array->items, array->nr, compare_refs, sorting); } static void append_literal(const char *cp, const char *ep, struct ref_formatting_state *state) @@ -3213,6 +3345,29 @@ int format_ref_array_item(struct ref_array_item *info, return 0; } +void print_formatted_ref_array(struct ref_array *array, struct ref_format *format) +{ + int total; + struct strbuf output = STRBUF_INIT, err = STRBUF_INIT; + + total = format->array_opts.max_count; + if (!total || array->nr < total) + total = array->nr; + for (int i = 0; i < total; i++) { + strbuf_reset(&err); + strbuf_reset(&output); + if (format_ref_array_item(array->items[i], format, &output, &err)) + die("%s", err.buf); + if (output.len || !format->array_opts.omit_empty) { + fwrite(output.buf, 1, output.len, stdout); + putchar('\n'); + } + } + + strbuf_release(&err); + strbuf_release(&output); +} + void pretty_print_ref(const char *name, const struct object_id *oid, struct ref_format *format) { @@ -3248,18 +3403,6 @@ static int parse_sorting_atom(const char *atom) return res; } -/* If no sorting option is given, use refname to sort as default */ -static struct ref_sorting *ref_default_sorting(void) -{ - static const char cstr_name[] = "refname"; - - struct ref_sorting *sorting = xcalloc(1, sizeof(*sorting)); - - sorting->next = NULL; - sorting->atom = parse_sorting_atom(cstr_name); - return sorting; -} - static void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg) { struct ref_sorting *s; @@ -3283,9 +3426,7 @@ struct ref_sorting *ref_sorting_options(struct string_list *options) struct string_list_item *item; struct ref_sorting *sorting = NULL, **tail = &sorting; - if (!options->nr) { - sorting = ref_default_sorting(); - } else { + if (options->nr) { for_each_string_list_item(item, options) parse_ref_sorting(tail, item->string); } diff --git a/ref-filter.h b/ref-filter.h index 1524bc463a..0ca28d2bba 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -3,10 +3,10 @@ #include "gettext.h" #include "oid-array.h" -#include "refs.h" #include "commit.h" #include "string-list.h" #include "strvec.h" +#include "commit-reach.h" /* Quoting styles */ #define QUOTE_NONE 0 @@ -19,10 +19,13 @@ #define FILTER_REFS_BRANCHES 0x0004 #define FILTER_REFS_REMOTES 0x0008 #define FILTER_REFS_OTHERS 0x0010 -#define FILTER_REFS_ALL (FILTER_REFS_TAGS | FILTER_REFS_BRANCHES | \ +#define FILTER_REFS_REGULAR (FILTER_REFS_TAGS | FILTER_REFS_BRANCHES | \ FILTER_REFS_REMOTES | FILTER_REFS_OTHERS) #define FILTER_REFS_DETACHED_HEAD 0x0020 -#define FILTER_REFS_KIND_MASK (FILTER_REFS_ALL | FILTER_REFS_DETACHED_HEAD) +#define FILTER_REFS_PSEUDOREFS 0x0040 +#define FILTER_REFS_ROOT_REFS (FILTER_REFS_DETACHED_HEAD | FILTER_REFS_PSEUDOREFS) +#define FILTER_REFS_KIND_MASK (FILTER_REFS_REGULAR | FILTER_REFS_DETACHED_HEAD | \ + FILTER_REFS_PSEUDOREFS) struct atom_value; struct ref_sorting; @@ -75,6 +78,11 @@ struct ref_filter { lines; int abbrev, verbose; + + struct { + struct contains_cache contains_cache; + struct contains_cache no_contains_cache; + } internal; }; struct ref_format { @@ -92,6 +100,11 @@ struct ref_format { /* List of bases for ahead-behind counts. */ struct string_list bases; + + struct { + int max_count; + int omit_empty; + } array_opts; }; #define REF_FILTER_INIT { \ @@ -126,6 +139,14 @@ struct ref_format { * filtered refs in the ref_array structure. */ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type); +/* + * Filter refs using the given ref_filter and type, sort the contents + * according to the given ref_sorting, format the filtered refs with the + * given ref_format, and print them to stdout. + */ +void filter_and_format_refs(struct ref_filter *filter, unsigned int type, + struct ref_sorting *sorting, + struct ref_format *format); /* Clear all memory allocated to ref_array */ void ref_array_clear(struct ref_array *array); /* Used to verify if the given format is correct and to parse out the used atoms */ @@ -151,6 +172,12 @@ char *get_head_description(void); void setup_ref_filter_porcelain_msg(void); /* + * Print up to maxcount ref_array elements to stdout using the given + * ref_format. + */ +void print_formatted_ref_array(struct ref_array *array, struct ref_format *format); + +/* * Print a single ref, outside of any ref-filter. Note that the * name must be a fully qualified refname. */ @@ -6,7 +6,6 @@ #include "revision.h" #include "tree.h" #include "tree-walk.h" -#include "worktree.h" /* Remember to update object flag allocation in object.h */ #define INCOMPLETE (1u<<10) @@ -33,17 +33,34 @@ /* * List of all available backends */ -static struct ref_storage_be *refs_backends = &refs_be_files; +static const struct ref_storage_be *refs_backends[] = { + [REF_STORAGE_FORMAT_FILES] = &refs_be_files, + [REF_STORAGE_FORMAT_REFTABLE] = &refs_be_reftable, +}; -static struct ref_storage_be *find_ref_storage_backend(const char *name) +static const struct ref_storage_be *find_ref_storage_backend(unsigned int ref_storage_format) { - struct ref_storage_be *be; - for (be = refs_backends; be; be = be->next) - if (!strcmp(be->name, name)) - return be; + if (ref_storage_format < ARRAY_SIZE(refs_backends)) + return refs_backends[ref_storage_format]; return NULL; } +unsigned int ref_storage_format_by_name(const char *name) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(refs_backends); i++) + if (refs_backends[i] && !strcmp(refs_backends[i]->name, name)) + return i; + return REF_STORAGE_FORMAT_UNKNOWN; +} + +const char *ref_storage_format_to_name(unsigned int ref_storage_format) +{ + const struct ref_storage_be *be = find_ref_storage_backend(ref_storage_format); + if (!be) + return "unknown"; + return be->name; +} + /* * How to handle various characters in refnames: * 0: An acceptable character for refs @@ -843,6 +860,47 @@ static int is_pseudoref_syntax(const char *refname) return 1; } +int is_pseudoref(struct ref_store *refs, const char *refname) +{ + static const char *const irregular_pseudorefs[] = { + "AUTO_MERGE", + "BISECT_EXPECTED_REV", + "NOTES_MERGE_PARTIAL", + "NOTES_MERGE_REF", + "MERGE_AUTOSTASH", + }; + struct object_id oid; + size_t i; + + if (!is_pseudoref_syntax(refname)) + return 0; + + if (ends_with(refname, "_HEAD")) { + refs_resolve_ref_unsafe(refs, refname, + RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, + &oid, NULL); + return !is_null_oid(&oid); + } + + for (i = 0; i < ARRAY_SIZE(irregular_pseudorefs); i++) + if (!strcmp(refname, irregular_pseudorefs[i])) { + refs_resolve_ref_unsafe(refs, refname, + RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, + &oid, NULL); + return !is_null_oid(&oid); + } + + return 0; +} + +int is_headref(struct ref_store *refs, const char *refname) +{ + if (!strcmp(refname, "HEAD")) + return refs_ref_exists(refs, refname); + + return 0; +} + static int is_current_worktree_ref(const char *ref) { return is_pseudoref_syntax(ref) || is_per_worktree_ref(ref); } @@ -1022,55 +1080,40 @@ static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid, const char *message, void *cb_data) { struct read_ref_at_cb *cb = cb_data; - int reached_count; cb->tz = tz; cb->date = timestamp; - /* - * It is not possible for cb->cnt == 0 on the first iteration because - * that special case is handled in read_ref_at(). - */ - if (cb->cnt > 0) - cb->cnt--; - reached_count = cb->cnt == 0 && !is_null_oid(ooid); - if (timestamp <= cb->at_time || reached_count) { + if (timestamp <= cb->at_time || cb->cnt == 0) { set_read_ref_cutoffs(cb, timestamp, tz, message); /* * we have not yet updated cb->[n|o]oid so they still * hold the values for the previous record. */ - if (!is_null_oid(&cb->ooid) && !oideq(&cb->ooid, noid)) - warning(_("log for ref %s has gap after %s"), + if (!is_null_oid(&cb->ooid)) { + oidcpy(cb->oid, noid); + if (!oideq(&cb->ooid, noid)) + warning(_("log for ref %s has gap after %s"), cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); - if (reached_count) - oidcpy(cb->oid, ooid); - else if (!is_null_oid(&cb->ooid) || cb->date == cb->at_time) + } + else if (cb->date == cb->at_time) oidcpy(cb->oid, noid); else if (!oideq(noid, cb->oid)) warning(_("log for ref %s unexpectedly ended on %s"), cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); + cb->reccnt++; + oidcpy(&cb->ooid, ooid); + oidcpy(&cb->noid, noid); cb->found_it = 1; + return 1; } cb->reccnt++; oidcpy(&cb->ooid, ooid); oidcpy(&cb->noid, noid); - return cb->found_it; -} - -static int read_ref_at_ent_newest(struct object_id *ooid UNUSED, - struct object_id *noid, - const char *email UNUSED, - timestamp_t timestamp, int tz, - const char *message, void *cb_data) -{ - struct read_ref_at_cb *cb = cb_data; - - set_read_ref_cutoffs(cb, timestamp, tz, message); - oidcpy(cb->oid, noid); - /* We just want the first entry */ - return 1; + if (cb->cnt > 0) + cb->cnt--; + return 0; } static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid, @@ -1082,7 +1125,7 @@ static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid set_read_ref_cutoffs(cb, timestamp, tz, message); oidcpy(cb->oid, ooid); - if (is_null_oid(cb->oid)) + if (cb->at_time && is_null_oid(cb->oid)) oidcpy(cb->oid, noid); /* We just want the first entry */ return 1; @@ -1105,14 +1148,24 @@ int read_ref_at(struct ref_store *refs, const char *refname, cb.cutoff_cnt = cutoff_cnt; cb.oid = oid; - if (cb.cnt == 0) { - refs_for_each_reflog_ent_reverse(refs, refname, read_ref_at_ent_newest, &cb); - return 0; - } - refs_for_each_reflog_ent_reverse(refs, refname, read_ref_at_ent, &cb); if (!cb.reccnt) { + if (cnt == 0) { + /* + * The caller asked for ref@{0}, and we had no entries. + * It's a bit subtle, but in practice all callers have + * prepped the "oid" field with the current value of + * the ref, which is the most reasonable fallback. + * + * We'll put dummy values into the out-parameters (so + * they're not just uninitialized garbage), and the + * caller can take our return value as a hint that + * we did not find any such reflog. + */ + set_read_ref_cutoffs(&cb, 0, 0, "empty reflog"); + return 1; + } if (flags & GET_OID_QUIETLY) exit(128); else @@ -1577,10 +1630,6 @@ struct ref_iterator *refs_ref_iterator_begin( if (trim) iter = prefix_ref_iterator_begin(iter, "", trim); - /* Sanity check for subclasses: */ - if (!iter->ordered) - BUG("reference iterator is not ordered"); - return iter; } @@ -1707,6 +1756,13 @@ int for_each_rawref(each_ref_fn fn, void *cb_data) return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data); } +int refs_for_each_include_root_refs(struct ref_store *refs, each_ref_fn fn, + void *cb_data) +{ + return do_for_each_ref(refs, "", NULL, fn, 0, + DO_FOR_EACH_INCLUDE_ROOT_REFS, cb_data); +} + static int qsort_strcmp(const void *va, const void *vb) { const char *a = *(const char **)va; @@ -1806,8 +1862,10 @@ static int refs_read_special_head(struct ref_store *ref_store, int result = -1; strbuf_addf(&full_path, "%s/%s", ref_store->gitdir, refname); - if (strbuf_read_file(&content, full_path.buf, 0) < 0) + if (strbuf_read_file(&content, full_path.buf, 0) < 0) { + *failure_errno = errno; goto done; + } result = parse_loose_ref_contents(content.buf, oid, referent, type, failure_errno); @@ -1818,15 +1876,45 @@ done: return result; } +static int is_special_ref(const char *refname) +{ + /* + * Special references are refs that have different semantics compared + * to "normal" refs. These refs can thus not be stored in the ref + * backend, but must always be accessed via the filesystem. The + * following refs are special: + * + * - FETCH_HEAD may contain multiple object IDs, and each one of them + * carries additional metadata like where it came from. + * + * - MERGE_HEAD may contain multiple object IDs when merging multiple + * heads. + * + * Reading, writing or deleting references must consistently go either + * through the filesystem (special refs) or through the reference + * backend (normal ones). + */ + static const char * const special_refs[] = { + "FETCH_HEAD", + "MERGE_HEAD", + }; + size_t i; + + for (i = 0; i < ARRAY_SIZE(special_refs); i++) + if (!strcmp(refname, special_refs[i])) + return 1; + + return 0; +} + int refs_read_raw_ref(struct ref_store *ref_store, const char *refname, struct object_id *oid, struct strbuf *referent, unsigned int *type, int *failure_errno) { assert(failure_errno); - if (!strcmp(refname, "FETCH_HEAD") || !strcmp(refname, "MERGE_HEAD")) { + if (is_special_ref(refname)) return refs_read_special_head(ref_store, refname, oid, referent, type, failure_errno); - } return ref_store->be->read_raw_ref(ref_store, refname, oid, referent, type, failure_errno); @@ -1928,11 +2016,9 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs, } /* backend functions */ -int refs_init_db(struct strbuf *err) +int refs_init_db(struct ref_store *refs, int flags, struct strbuf *err) { - struct ref_store *refs = get_main_ref_store(the_repository); - - return refs->be->init_db(refs, err); + return refs->be->init_db(refs, flags, err); } const char *resolve_ref_unsafe(const char *refname, int resolve_flags, @@ -2029,12 +2115,12 @@ static struct ref_store *ref_store_init(struct repository *repo, const char *gitdir, unsigned int flags) { - const char *be_name = "files"; - struct ref_storage_be *be = find_ref_storage_backend(be_name); + const struct ref_storage_be *be; struct ref_store *refs; + be = find_ref_storage_backend(repo->ref_storage_format); if (!be) - BUG("reference backend %s is unknown", be_name); + BUG("reference backend is unknown"); refs = be->init(repo, gitdir, flags); return refs; @@ -2469,18 +2555,33 @@ cleanup: return ret; } -int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data) +struct do_for_each_reflog_help { + each_reflog_fn *fn; + void *cb_data; +}; + +static int do_for_each_reflog_helper(struct repository *r UNUSED, + const char *refname, + const struct object_id *oid UNUSED, + int flags, + void *cb_data) +{ + struct do_for_each_reflog_help *hp = cb_data; + return hp->fn(refname, hp->cb_data); +} + +int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_data) { struct ref_iterator *iter; - struct do_for_each_ref_help hp = { fn, cb_data }; + struct do_for_each_reflog_help hp = { fn, cb_data }; iter = refs->be->reflog_iterator_begin(refs); return do_for_each_repo_ref_iterator(the_repository, iter, - do_for_each_ref_helper, &hp); + do_for_each_reflog_helper, &hp); } -int for_each_reflog(each_ref_fn fn, void *cb_data) +int for_each_reflog(each_reflog_fn fn, void *cb_data) { return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data); } @@ -2599,13 +2700,55 @@ void ref_transaction_for_each_queued_update(struct ref_transaction *transaction, int refs_delete_refs(struct ref_store *refs, const char *logmsg, struct string_list *refnames, unsigned int flags) { + struct ref_transaction *transaction; + struct strbuf err = STRBUF_INIT; + struct string_list_item *item; + int ret = 0, failures = 0; char *msg; - int retval; + + if (!refnames->nr) + return 0; msg = normalize_reflog_message(logmsg); - retval = refs->be->delete_refs(refs, msg, refnames, flags); + + /* + * Since we don't check the references' old_oids, the + * individual updates can't fail, so we can pack all of the + * updates into a single transaction. + */ + transaction = ref_store_transaction_begin(refs, &err); + if (!transaction) { + ret = error("%s", err.buf); + goto out; + } + + for_each_string_list_item(item, refnames) { + ret = ref_transaction_delete(transaction, item->string, + NULL, flags, msg, &err); + if (ret) { + warning(_("could not delete reference %s: %s"), + item->string, err.buf); + strbuf_reset(&err); + failures = 1; + } + } + + ret = ref_transaction_commit(transaction, &err); + if (ret) { + if (refnames->nr == 1) + error(_("could not delete reference %s: %s"), + refnames->items[0].string, err.buf); + else + error(_("could not delete references: %s"), err.buf); + } + +out: + if (!ret && failures) + ret = -1; + ref_transaction_free(transaction); + strbuf_release(&err); free(msg); - return retval; + return ret; } int delete_refs(const char *msg, struct string_list *refnames, @@ -11,6 +11,9 @@ struct string_list; struct string_list_item; struct worktree; +unsigned int ref_storage_format_by_name(const char *name); +const char *ref_storage_format_to_name(unsigned int ref_storage_format); + /* * Resolve a reference, recursively following symbolic refererences. * @@ -56,7 +59,7 @@ struct worktree; * Even with RESOLVE_REF_ALLOW_BAD_NAME, names that escape the refs/ * directory and do not consist of all caps and underscores cannot be * resolved. The function returns NULL for such ref names. - * Caps and underscores refers to the special refs, such as HEAD, + * Caps and underscores refers to the pseudorefs, such as HEAD, * FETCH_HEAD and friends, that all live outside of the refs/ directory. */ #define RESOLVE_REF_READING 0x01 @@ -123,7 +126,9 @@ int should_autocreate_reflog(const char *refname); int is_branch(const char *refname); -int refs_init_db(struct strbuf *err); +#define REFS_INIT_DB_IS_WORKTREE (1 << 0) + +int refs_init_db(struct ref_store *refs, int flags, struct strbuf *err); /* * Return the peeled value of the oid currently being iterated via @@ -394,6 +399,12 @@ int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data); int for_each_rawref(each_ref_fn fn, void *cb_data); /* + * Iterates over all refs including root refs, i.e. pseudorefs and HEAD. + */ +int refs_for_each_include_root_refs(struct ref_store *refs, each_ref_fn fn, + void *cb_data); + +/* * Normalizes partial refs to their fully qualified form. * Will prepend <prefix> to the <pattern> if it doesn't start with 'refs/'. * <prefix> will default to 'refs/' if NULL. @@ -435,7 +446,20 @@ int refs_create_reflog(struct ref_store *refs, const char *refname, struct strbuf *err); int safe_create_reflog(const char *refname, struct strbuf *err); -/** Reads log for the value of ref during at_time. **/ +/** + * Reads log for the value of ref during at_time (in which case "cnt" should be + * negative) or the reflog "cnt" entries from the top (in which case "at_time" + * should be 0). + * + * If we found the reflog entry in question, returns 0 (and details of the + * entry can be found in the out-parameters). + * + * If we ran out of reflog entries, the out-parameters are filled with the + * details of the oldest entry we did find, and the function returns 1. Note + * that there is one important special case here! If the reflog was empty + * and the caller asked for the 0-th cnt, we will return "1" but leave the + * "oid" field untouched. + **/ int read_ref_at(struct ref_store *refs, const char *refname, unsigned int flags, timestamp_t at_time, int cnt, @@ -530,11 +554,18 @@ int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_dat int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data); /* + * The signature for the callback function for the {refs_,}for_each_reflog() + * functions below. The memory pointed to by the refname argument is only + * guaranteed to be valid for the duration of a single callback invocation. + */ +typedef int each_reflog_fn(const char *refname, void *cb_data); + +/* * Calls the specified function for each reflog file until it returns nonzero, * and returns the value. Reflog file order is unspecified. */ -int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data); -int for_each_reflog(each_ref_fn fn, void *cb_data); +int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_data); +int for_each_reflog(each_reflog_fn fn, void *cb_data); #define REFNAME_ALLOW_ONELEVEL 1 #define REFNAME_REFSPEC_PATTERN 2 @@ -1018,4 +1049,7 @@ extern struct ref_namespace_info ref_namespace[NAMESPACE__COUNT]; */ void update_ref_namespace(enum ref_namespace namespace, char *ref); +int is_pseudoref(struct ref_store *refs, const char *refname); +int is_headref(struct ref_store *refs, const char *refname); + #endif /* REFS_H */ diff --git a/refs/debug.c b/refs/debug.c index b7ffc4ce67..c7531b17f0 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -33,10 +33,10 @@ struct ref_store *maybe_debug_wrap_ref_store(const char *gitdir, struct ref_stor return (struct ref_store *)res; } -static int debug_init_db(struct ref_store *refs, struct strbuf *err) +static int debug_init_db(struct ref_store *refs, int flags, struct strbuf *err) { struct debug_ref_store *drefs = (struct debug_ref_store *)refs; - int res = drefs->refs->be->init_db(drefs->refs, err); + int res = drefs->refs->be->init_db(drefs->refs, flags, err); trace_printf_key(&trace_refs, "init_db: %d\n", res); return res; } @@ -143,20 +143,6 @@ static int debug_create_symref(struct ref_store *ref_store, return res; } -static int debug_delete_refs(struct ref_store *ref_store, const char *msg, - struct string_list *refnames, unsigned int flags) -{ - struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store; - int res = - drefs->refs->be->delete_refs(drefs->refs, msg, refnames, flags); - int i; - trace_printf_key(&trace_refs, "delete_refs {\n"); - for (i = 0; i < refnames->nr; i++) - trace_printf_key(&trace_refs, "%s\n", refnames->items[i].string); - trace_printf_key(&trace_refs, "}: %d\n", res); - return res; -} - static int debug_rename_ref(struct ref_store *ref_store, const char *oldref, const char *newref, const char *logmsg) { @@ -195,7 +181,6 @@ static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator) trace_printf_key(&trace_refs, "iterator_advance: %s (0)\n", diter->iter->refname); - diter->base.ordered = diter->iter->ordered; diter->base.refname = diter->iter->refname; diter->base.oid = diter->iter->oid; diter->base.flags = diter->iter->flags; @@ -236,7 +221,7 @@ debug_ref_iterator_begin(struct ref_store *ref_store, const char *prefix, drefs->refs->be->iterator_begin(drefs->refs, prefix, exclude_patterns, flags); struct debug_ref_iterator *diter = xcalloc(1, sizeof(*diter)); - base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable, 1); + base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable); diter->iter = res; trace_printf_key(&trace_refs, "ref_iterator_begin: \"%s\" (0x%x)\n", prefix, flags); @@ -440,7 +425,6 @@ static int debug_reflog_expire(struct ref_store *ref_store, const char *refname, } struct ref_storage_be refs_be_debug = { - .next = NULL, .name = "debug", .init = NULL, .init_db = debug_init_db, @@ -458,7 +442,6 @@ struct ref_storage_be refs_be_debug = { .pack_refs = debug_pack_refs, .create_symref = debug_create_symref, - .delete_refs = debug_delete_refs, .rename_ref = debug_rename_ref, .copy_ref = debug_copy_ref, diff --git a/refs/files-backend.c b/refs/files-backend.c index db5c0c7a72..a098d14ea0 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1,5 +1,4 @@ #include "../git-compat-util.h" -#include "../config.h" #include "../copy.h" #include "../environment.h" #include "../gettext.h" @@ -19,7 +18,6 @@ #include "../dir.h" #include "../chdir-notify.h" #include "../setup.h" -#include "../worktree.h" #include "../wrapper.h" #include "../write-or-die.h" #include "../revision.h" @@ -231,6 +229,38 @@ static void add_per_worktree_entries_to_dir(struct ref_dir *dir, const char *dir } } +static void loose_fill_ref_dir_regular_file(struct files_ref_store *refs, + const char *refname, + struct ref_dir *dir) +{ + struct object_id oid; + int flag; + + if (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING, + &oid, &flag)) { + oidclr(&oid); + flag |= REF_ISBROKEN; + } else if (is_null_oid(&oid)) { + /* + * It is so astronomically unlikely + * that null_oid is the OID of an + * actual object that we consider its + * appearance in a loose reference + * file to be repo corruption + * (probably due to a software bug). + */ + flag |= REF_ISBROKEN; + } + + if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { + if (!refname_is_safe(refname)) + die("loose refname is dangerous: %s", refname); + oidclr(&oid); + flag |= REF_BAD_NAME | REF_ISBROKEN; + } + add_entry_to_dir(dir, create_ref_entry(refname, &oid, flag)); +} + /* * Read the loose references from the namespace dirname into dir * (without recursing). dirname must end with '/'. dir must be the @@ -259,8 +289,6 @@ static void loose_fill_ref_dir(struct ref_store *ref_store, strbuf_add(&refname, dirname, dirnamelen); while ((de = readdir(d)) != NULL) { - struct object_id oid; - int flag; unsigned char dtype; if (de->d_name[0] == '.') @@ -276,33 +304,7 @@ static void loose_fill_ref_dir(struct ref_store *ref_store, create_dir_entry(dir->cache, refname.buf, refname.len)); } else if (dtype == DT_REG) { - if (!refs_resolve_ref_unsafe(&refs->base, - refname.buf, - RESOLVE_REF_READING, - &oid, &flag)) { - oidclr(&oid); - flag |= REF_ISBROKEN; - } else if (is_null_oid(&oid)) { - /* - * It is so astronomically unlikely - * that null_oid is the OID of an - * actual object that we consider its - * appearance in a loose reference - * file to be repo corruption - * (probably due to a software bug). - */ - flag |= REF_ISBROKEN; - } - - if (check_refname_format(refname.buf, - REFNAME_ALLOW_ONELEVEL)) { - if (!refname_is_safe(refname.buf)) - die("loose refname is dangerous: %s", refname.buf); - oidclr(&oid); - flag |= REF_BAD_NAME | REF_ISBROKEN; - } - add_entry_to_dir(dir, - create_ref_entry(refname.buf, &oid, flag)); + loose_fill_ref_dir_regular_file(refs, refname.buf, dir); } strbuf_setlen(&refname, dirnamelen); } @@ -313,9 +315,59 @@ static void loose_fill_ref_dir(struct ref_store *ref_store, add_per_worktree_entries_to_dir(dir, dirname); } -static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs) +/* + * Add pseudorefs to the ref dir by parsing the directory for any files + * which follow the pseudoref syntax. + */ +static void add_pseudoref_and_head_entries(struct ref_store *ref_store, + struct ref_dir *dir, + const char *dirname) +{ + struct files_ref_store *refs = + files_downcast(ref_store, REF_STORE_READ, "fill_ref_dir"); + struct strbuf path = STRBUF_INIT, refname = STRBUF_INIT; + struct dirent *de; + size_t dirnamelen; + DIR *d; + + files_ref_path(refs, &path, dirname); + + d = opendir(path.buf); + if (!d) { + strbuf_release(&path); + return; + } + + strbuf_addstr(&refname, dirname); + dirnamelen = refname.len; + + while ((de = readdir(d)) != NULL) { + unsigned char dtype; + + if (de->d_name[0] == '.') + continue; + if (ends_with(de->d_name, ".lock")) + continue; + strbuf_addstr(&refname, de->d_name); + + dtype = get_dtype(de, &path, 1); + if (dtype == DT_REG && (is_pseudoref(ref_store, de->d_name) || + is_headref(ref_store, de->d_name))) + loose_fill_ref_dir_regular_file(refs, refname.buf, dir); + + strbuf_setlen(&refname, dirnamelen); + } + strbuf_release(&refname); + strbuf_release(&path); + closedir(d); +} + +static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs, + unsigned int flags) { if (!refs->loose) { + struct ref_dir *dir; + /* * Mark the top-level directory complete because we * are about to read the only subdirectory that can @@ -326,12 +378,17 @@ static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs) /* We're going to fill the top level ourselves: */ refs->loose->root->flag &= ~REF_INCOMPLETE; + dir = get_ref_dir(refs->loose->root); + + if (flags & DO_FOR_EACH_INCLUDE_ROOT_REFS) + add_pseudoref_and_head_entries(dir->cache->ref_store, dir, + refs->loose->root->name); + /* * Add an incomplete entry for "refs/" (to be filled * lazily): */ - add_entry_to_dir(get_ref_dir(refs->loose->root), - create_dir_entry(refs->loose, "refs/", 5)); + add_entry_to_dir(dir, create_dir_entry(refs->loose, "refs/", 5)); } return refs->loose; } @@ -859,7 +916,7 @@ static struct ref_iterator *files_ref_iterator_begin( * disk, and re-reads it if not. */ - loose_iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), + loose_iter = cache_ref_iterator_begin(get_loose_ref_cache(refs, flags), prefix, ref_store->repo, 1); /* @@ -881,8 +938,7 @@ static struct ref_iterator *files_ref_iterator_begin( CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable, - overlay_iter->ordered); + base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable); iter->iter0 = overlay_iter; iter->repo = ref_store->repo; iter->flags = flags; @@ -1220,7 +1276,7 @@ static int files_pack_refs(struct ref_store *ref_store, packed_refs_lock(refs->packed_ref_store, LOCK_DIE_ON_ERROR, &err); - iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL, + iter = cache_ref_iterator_begin(get_loose_ref_cache(refs, 0), NULL, the_repository, 0); while ((ok = ref_iterator_advance(iter)) == ITER_OK) { /* @@ -1265,54 +1321,6 @@ static int files_pack_refs(struct ref_store *ref_store, return 0; } -static int files_delete_refs(struct ref_store *ref_store, const char *msg, - struct string_list *refnames, unsigned int flags) -{ - struct files_ref_store *refs = - files_downcast(ref_store, REF_STORE_WRITE, "delete_refs"); - struct strbuf err = STRBUF_INIT; - int i, result = 0; - - if (!refnames->nr) - return 0; - - if (packed_refs_lock(refs->packed_ref_store, 0, &err)) - goto error; - - if (refs_delete_refs(refs->packed_ref_store, msg, refnames, flags)) { - packed_refs_unlock(refs->packed_ref_store); - goto error; - } - - packed_refs_unlock(refs->packed_ref_store); - - for (i = 0; i < refnames->nr; i++) { - const char *refname = refnames->items[i].string; - - if (refs_delete_ref(&refs->base, msg, refname, NULL, flags)) - result |= error(_("could not remove reference %s"), refname); - } - - strbuf_release(&err); - return result; - -error: - /* - * If we failed to rewrite the packed-refs file, then it is - * unsafe to try to remove loose refs, because doing so might - * expose an obsolete packed value for a reference that might - * even point at an object that has been garbage collected. - */ - if (refnames->nr == 1) - error(_("could not delete reference %s: %s"), - refnames->items[0].string, err.buf); - else - error(_("could not delete references: %s"), err.buf); - - strbuf_release(&err); - return -1; -} - /* * People using contrib's git-new-workdir have .git/logs/refs -> * /some/other/path/.git/logs/refs, and that may live on another device. @@ -2166,10 +2174,8 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store, struct files_reflog_iterator { struct ref_iterator base; - struct ref_store *ref_store; struct dir_iterator *dir_iterator; - struct object_id oid; }; static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) @@ -2180,25 +2186,13 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) int ok; while ((ok = dir_iterator_advance(diter)) == ITER_OK) { - int flags; - if (!S_ISREG(diter->st.st_mode)) continue; - if (diter->basename[0] == '.') - continue; - if (ends_with(diter->basename, ".lock")) + if (check_refname_format(diter->basename, + REFNAME_ALLOW_ONELEVEL)) continue; - if (!refs_resolve_ref_unsafe(iter->ref_store, - diter->relative_path, 0, - &iter->oid, &flags)) { - error("bad ref for %s", diter->path.buf); - continue; - } - iter->base.refname = diter->relative_path; - iter->base.oid = &iter->oid; - iter->base.flags = flags; return ITER_OK; } @@ -2243,7 +2237,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, strbuf_addf(&sb, "%s/logs", gitdir); - diter = dir_iterator_begin(sb.buf, 0); + diter = dir_iterator_begin(sb.buf, DIR_ITERATOR_SORTED); if (!diter) { strbuf_release(&sb); return empty_ref_iterator_begin(); @@ -2252,7 +2246,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 0); + base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable); iter->dir_iterator = diter; iter->ref_store = ref_store; strbuf_release(&sb); @@ -2260,32 +2254,6 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, return ref_iterator; } -static enum iterator_selection reflog_iterator_select( - struct ref_iterator *iter_worktree, - struct ref_iterator *iter_common, - void *cb_data UNUSED) -{ - if (iter_worktree) { - /* - * We're a bit loose here. We probably should ignore - * common refs if they are accidentally added as - * per-worktree refs. - */ - return ITER_SELECT_0; - } else if (iter_common) { - if (parse_worktree_ref(iter_common->refname, NULL, NULL, - NULL) == REF_WORKTREE_SHARED) - return ITER_SELECT_1; - - /* - * The main ref store may contain main worktree's - * per-worktree refs, which should be ignored - */ - return ITER_SKIP_1; - } else - return ITER_DONE; -} - static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store) { struct files_ref_store *refs = @@ -2296,9 +2264,9 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st return reflog_iterator_begin(ref_store, refs->gitcommondir); } else { return merge_ref_iterator_begin( - 0, reflog_iterator_begin(ref_store, refs->base.gitdir), + reflog_iterator_begin(ref_store, refs->base.gitdir), reflog_iterator_begin(ref_store, refs->gitcommondir), - reflog_iterator_select, refs); + ref_iterator_select, refs); } } @@ -3268,28 +3236,52 @@ static int files_reflog_expire(struct ref_store *ref_store, return -1; } -static int files_init_db(struct ref_store *ref_store, struct strbuf *err UNUSED) +static int files_init_db(struct ref_store *ref_store, + int flags, + struct strbuf *err UNUSED) { struct files_ref_store *refs = files_downcast(ref_store, REF_STORE_WRITE, "init_db"); struct strbuf sb = STRBUF_INIT; /* - * Create .git/refs/{heads,tags} + * We need to create a "refs" dir in any case so that older versions of + * Git can tell that this is a repository. This serves two main purposes: + * + * - Clients will know to stop walking the parent-directory chain when + * detecting the Git repository. Otherwise they may end up detecting + * a Git repository in a parent directory instead. + * + * - Instead of failing to detect a repository with unknown reference + * format altogether, old clients will print an error saying that + * they do not understand the reference format extension. */ - files_ref_path(refs, &sb, "refs/heads"); + strbuf_addf(&sb, "%s/refs", ref_store->gitdir); safe_create_dir(sb.buf, 1); + adjust_shared_perm(sb.buf); - strbuf_reset(&sb); - files_ref_path(refs, &sb, "refs/tags"); - safe_create_dir(sb.buf, 1); + /* + * There is no need to create directories for common refs when creating + * a worktree ref store. + */ + if (!(flags & REFS_INIT_DB_IS_WORKTREE)) { + /* + * Create .git/refs/{heads,tags} + */ + strbuf_reset(&sb); + files_ref_path(refs, &sb, "refs/heads"); + safe_create_dir(sb.buf, 1); + + strbuf_reset(&sb); + files_ref_path(refs, &sb, "refs/tags"); + safe_create_dir(sb.buf, 1); + } strbuf_release(&sb); return 0; } struct ref_storage_be refs_be_files = { - .next = NULL, .name = "files", .init = files_ref_store_create, .init_db = files_init_db, @@ -3300,7 +3292,6 @@ struct ref_storage_be refs_be_files = { .pack_refs = files_pack_refs, .create_symref = files_create_symref, - .delete_refs = files_delete_refs, .rename_ref = files_rename_ref, .copy_ref = files_copy_ref, diff --git a/refs/iterator.c b/refs/iterator.c index 6b680f610e..9db8b056d5 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -25,11 +25,9 @@ int ref_iterator_abort(struct ref_iterator *ref_iterator) } void base_ref_iterator_init(struct ref_iterator *iter, - struct ref_iterator_vtable *vtable, - int ordered) + struct ref_iterator_vtable *vtable) { iter->vtable = vtable; - iter->ordered = !!ordered; iter->refname = NULL; iter->oid = NULL; iter->flags = 0; @@ -74,7 +72,7 @@ struct ref_iterator *empty_ref_iterator_begin(void) struct empty_ref_iterator *iter = xcalloc(1, sizeof(*iter)); struct ref_iterator *ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable, 1); + base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable); return ref_iterator; } @@ -98,6 +96,49 @@ struct merge_ref_iterator { struct ref_iterator **current; }; +enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree, + struct ref_iterator *iter_common, + void *cb_data UNUSED) +{ + if (iter_worktree && !iter_common) { + /* + * Return the worktree ref if there are no more common refs. + */ + return ITER_SELECT_0; + } else if (iter_common) { + /* + * In case we have pending worktree and common refs we need to + * yield them based on their lexicographical order. Worktree + * refs that have the same name as common refs shadow the + * latter. + */ + if (iter_worktree) { + int cmp = strcmp(iter_worktree->refname, + iter_common->refname); + if (cmp < 0) + return ITER_SELECT_0; + else if (!cmp) + return ITER_SELECT_0_SKIP_1; + } + + /* + * We now know that the lexicographically-next ref is a common + * ref. When the common ref is a shared one we return it. + */ + if (parse_worktree_ref(iter_common->refname, NULL, NULL, + NULL) == REF_WORKTREE_SHARED) + return ITER_SELECT_1; + + /* + * Otherwise, if the common ref is a per-worktree ref we skip + * it because it would belong to the main worktree, not ours. + */ + return ITER_SKIP_1; + } else { + return ITER_DONE; + } +} + static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator) { struct merge_ref_iterator *iter = @@ -207,7 +248,6 @@ static struct ref_iterator_vtable merge_ref_iterator_vtable = { }; struct ref_iterator *merge_ref_iterator_begin( - int ordered, struct ref_iterator *iter0, struct ref_iterator *iter1, ref_iterator_select_fn *select, void *cb_data) { @@ -222,7 +262,7 @@ struct ref_iterator *merge_ref_iterator_begin( * references through only if they exist in both iterators. */ - base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable, ordered); + base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable); iter->iter0 = iter0; iter->iter1 = iter1; iter->select = select; @@ -271,12 +311,9 @@ struct ref_iterator *overlay_ref_iterator_begin( } else if (is_empty_ref_iterator(back)) { ref_iterator_abort(back); return front; - } else if (!front->ordered || !back->ordered) { - BUG("overlay_ref_iterator requires ordered inputs"); } - return merge_ref_iterator_begin(1, front, back, - overlay_iterator_select, NULL); + return merge_ref_iterator_begin(front, back, overlay_iterator_select, NULL); } struct prefix_ref_iterator { @@ -315,16 +352,12 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator) if (cmp > 0) { /* - * If the source iterator is ordered, then we + * As the source iterator is ordered, we * can stop the iteration as soon as we see a * refname that comes after the prefix: */ - if (iter->iter0->ordered) { - ok = ref_iterator_abort(iter->iter0); - break; - } else { - continue; - } + ok = ref_iterator_abort(iter->iter0); + break; } if (iter->trim) { @@ -396,7 +429,7 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable, iter0->ordered); + base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable); iter->iter0 = iter0; iter->prefix = xstrdup(prefix); diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 59c78d7941..4e826c05ff 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1,5 +1,4 @@ #include "../git-compat-util.h" -#include "../alloc.h" #include "../config.h" #include "../gettext.h" #include "../hash.h" @@ -1112,7 +1111,7 @@ static struct ref_iterator *packed_ref_iterator_begin( CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable, 1); + base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable); if (exclude_patterns) populate_excluded_jump_list(iter, snapshot, exclude_patterns); @@ -1246,6 +1245,7 @@ static const char PACKED_REFS_HEADER[] = "# pack-refs with: peeled fully-peeled sorted \n"; static int packed_init_db(struct ref_store *ref_store UNUSED, + int flags UNUSED, struct strbuf *err UNUSED) { /* Nothing to do. */ @@ -1688,55 +1688,6 @@ static int packed_initial_transaction_commit(struct ref_store *ref_store UNUSED, return ref_transaction_commit(transaction, err); } -static int packed_delete_refs(struct ref_store *ref_store, const char *msg, - struct string_list *refnames, unsigned int flags) -{ - struct packed_ref_store *refs = - packed_downcast(ref_store, REF_STORE_WRITE, "delete_refs"); - struct strbuf err = STRBUF_INIT; - struct ref_transaction *transaction; - struct string_list_item *item; - int ret; - - (void)refs; /* We need the check above, but don't use the variable */ - - if (!refnames->nr) - return 0; - - /* - * Since we don't check the references' old_oids, the - * individual updates can't fail, so we can pack all of the - * updates into a single transaction. - */ - - transaction = ref_store_transaction_begin(ref_store, &err); - if (!transaction) - return -1; - - for_each_string_list_item(item, refnames) { - if (ref_transaction_delete(transaction, item->string, NULL, - flags, msg, &err)) { - warning(_("could not delete reference %s: %s"), - item->string, err.buf); - strbuf_reset(&err); - } - } - - ret = ref_transaction_commit(transaction, &err); - - if (ret) { - if (refnames->nr == 1) - error(_("could not delete reference %s: %s"), - refnames->items[0].string, err.buf); - else - error(_("could not delete references: %s"), err.buf); - } - - ref_transaction_free(transaction); - strbuf_release(&err); - return ret; -} - static int packed_pack_refs(struct ref_store *ref_store UNUSED, struct pack_refs_opts *pack_opts UNUSED) { @@ -1754,7 +1705,6 @@ static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_s } struct ref_storage_be refs_be_packed = { - .next = NULL, .name = "packed", .init = packed_ref_store_create, .init_db = packed_init_db, @@ -1765,7 +1715,6 @@ struct ref_storage_be refs_be_packed = { .pack_refs = packed_pack_refs, .create_symref = NULL, - .delete_refs = packed_delete_refs, .rename_ref = NULL, .copy_ref = NULL, diff --git a/refs/ref-cache.c b/refs/ref-cache.c index 6e3b725245..9f9797209a 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -1,5 +1,4 @@ #include "../git-compat-util.h" -#include "../alloc.h" #include "../hash.h" #include "../refs.h" #include "../repository.h" @@ -487,7 +486,7 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable, 1); + base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable); ALLOC_GROW(iter->levels, 10, iter->levels_alloc); iter->levels_nr = 1; diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 9db8aec4da..56641aa57a 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -260,6 +260,12 @@ enum do_for_each_ref_flags { * INCLUDE_BROKEN, since they are otherwise not included at all. */ DO_FOR_EACH_OMIT_DANGLING_SYMREFS = (1 << 2), + + /* + * Include root refs i.e. HEAD and pseudorefs along with the regular + * refs. + */ + DO_FOR_EACH_INCLUDE_ROOT_REFS = (1 << 3), }; /* @@ -312,13 +318,6 @@ enum do_for_each_ref_flags { */ struct ref_iterator { struct ref_iterator_vtable *vtable; - - /* - * Does this `ref_iterator` iterate over references in order - * by refname? - */ - unsigned int ordered : 1; - const char *refname; const struct object_id *oid; unsigned int flags; @@ -387,14 +386,21 @@ typedef enum iterator_selection ref_iterator_select_fn( void *cb_data); /* + * An implementation of ref_iterator_select_fn that merges worktree and common + * refs. Per-worktree refs from the common iterator are ignored, worktree refs + * override common refs. Refs are selected lexicographically. + */ +enum iterator_selection ref_iterator_select(struct ref_iterator *iter_worktree, + struct ref_iterator *iter_common, + void *cb_data); + +/* * Iterate over the entries from iter0 and iter1, with the values * interleaved as directed by the select function. The iterator takes * ownership of iter0 and iter1 and frees them when the iteration is - * over. A derived class should set `ordered` to 1 or 0 based on - * whether it generates its output in order by reference name. + * over. */ struct ref_iterator *merge_ref_iterator_begin( - int ordered, struct ref_iterator *iter0, struct ref_iterator *iter1, ref_iterator_select_fn *select, void *cb_data); @@ -423,8 +429,6 @@ struct ref_iterator *overlay_ref_iterator_begin( * As an convenience to callers, if prefix is the empty string and * trim is zero, this function returns iter0 directly, without * wrapping it. - * - * The resulting ref_iterator is ordered if iter0 is. */ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, const char *prefix, @@ -435,14 +439,11 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, /* * Base class constructor for ref_iterators. Initialize the * ref_iterator part of iter, setting its vtable pointer as specified. - * `ordered` should be set to 1 if the iterator will iterate over - * references in order by refname; otherwise it should be set to 0. * This is meant to be called only by the initializers of derived * classes. */ void base_ref_iterator_init(struct ref_iterator *iter, - struct ref_iterator_vtable *vtable, - int ordered); + struct ref_iterator_vtable *vtable); /* * Base class destructor for ref_iterators. Destroy the ref_iterator @@ -529,7 +530,9 @@ typedef struct ref_store *ref_store_init_fn(struct repository *repo, const char *gitdir, unsigned int flags); -typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err); +typedef int ref_init_db_fn(struct ref_store *refs, + int flags, + struct strbuf *err); typedef int ref_transaction_prepare_fn(struct ref_store *refs, struct ref_transaction *transaction, @@ -553,8 +556,6 @@ typedef int create_symref_fn(struct ref_store *ref_store, const char *ref_target, const char *refs_heads_master, const char *logmsg); -typedef int delete_refs_fn(struct ref_store *ref_store, const char *msg, - struct string_list *refnames, unsigned int flags); typedef int rename_ref_fn(struct ref_store *ref_store, const char *oldref, const char *newref, const char *logmsg); @@ -665,7 +666,6 @@ typedef int read_symbolic_ref_fn(struct ref_store *ref_store, const char *refnam struct strbuf *referent); struct ref_storage_be { - struct ref_storage_be *next; const char *name; ref_store_init_fn *init; ref_init_db_fn *init_db; @@ -677,7 +677,6 @@ struct ref_storage_be { pack_refs_fn *pack_refs; create_symref_fn *create_symref; - delete_refs_fn *delete_refs; rename_ref_fn *rename_ref; copy_ref_fn *copy_ref; @@ -695,6 +694,7 @@ struct ref_storage_be { }; extern struct ref_storage_be refs_be_files; +extern struct ref_storage_be refs_be_reftable; extern struct ref_storage_be refs_be_packed; /* diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c new file mode 100644 index 0000000000..eaa82967ee --- /dev/null +++ b/refs/reftable-backend.c @@ -0,0 +1,2249 @@ +#include "../git-compat-util.h" +#include "../abspath.h" +#include "../chdir-notify.h" +#include "../environment.h" +#include "../gettext.h" +#include "../hash.h" +#include "../hex.h" +#include "../iterator.h" +#include "../ident.h" +#include "../lockfile.h" +#include "../object.h" +#include "../path.h" +#include "../refs.h" +#include "../reftable/reftable-stack.h" +#include "../reftable/reftable-record.h" +#include "../reftable/reftable-error.h" +#include "../reftable/reftable-iterator.h" +#include "../reftable/reftable-merged.h" +#include "../setup.h" +#include "../strmap.h" +#include "refs-internal.h" + +/* + * Used as a flag in ref_update::flags when the ref_update was via an + * update to HEAD. + */ +#define REF_UPDATE_VIA_HEAD (1 << 8) + +struct reftable_ref_store { + struct ref_store base; + + /* + * The main stack refers to the common dir and thus contains common + * refs as well as refs of the main repository. + */ + struct reftable_stack *main_stack; + /* + * The worktree stack refers to the gitdir in case the refdb is opened + * via a worktree. It thus contains the per-worktree refs. + */ + struct reftable_stack *worktree_stack; + /* + * Map of worktree stacks by their respective worktree names. The map + * is populated lazily when we try to resolve `worktrees/$worktree` refs. + */ + struct strmap worktree_stacks; + struct reftable_write_options write_options; + + unsigned int store_flags; + int err; +}; + +/* + * Downcast ref_store to reftable_ref_store. Die if ref_store is not a + * reftable_ref_store. required_flags is compared with ref_store's store_flags + * to ensure the ref_store has all required capabilities. "caller" is used in + * any necessary error messages. + */ +static struct reftable_ref_store *reftable_be_downcast(struct ref_store *ref_store, + unsigned int required_flags, + const char *caller) +{ + struct reftable_ref_store *refs; + + if (ref_store->be != &refs_be_reftable) + BUG("ref_store is type \"%s\" not \"reftables\" in %s", + ref_store->be->name, caller); + + refs = (struct reftable_ref_store *)ref_store; + + if ((refs->store_flags & required_flags) != required_flags) + BUG("operation %s requires abilities 0x%x, but only have 0x%x", + caller, required_flags, refs->store_flags); + + return refs; +} + +/* + * Some refs are global to the repository (refs/heads/{*}), while others are + * local to the worktree (eg. HEAD, refs/bisect/{*}). We solve this by having + * multiple separate databases (ie. multiple reftable/ directories), one for + * the shared refs, one for the current worktree refs, and one for each + * additional worktree. For reading, we merge the view of both the shared and + * the current worktree's refs, when necessary. + * + * This function also optionally assigns the rewritten reference name that is + * local to the stack. This translation is required when using worktree refs + * like `worktrees/$worktree/refs/heads/foo` as worktree stacks will store + * those references in their normalized form. + */ +static struct reftable_stack *stack_for(struct reftable_ref_store *store, + const char *refname, + const char **rewritten_ref) +{ + const char *wtname; + int wtname_len; + + if (!refname) + return store->main_stack; + + switch (parse_worktree_ref(refname, &wtname, &wtname_len, rewritten_ref)) { + case REF_WORKTREE_OTHER: { + static struct strbuf wtname_buf = STRBUF_INIT; + struct strbuf wt_dir = STRBUF_INIT; + struct reftable_stack *stack; + + /* + * We're using a static buffer here so that we don't need to + * allocate the worktree name whenever we look up a reference. + * This could be avoided if the strmap interface knew how to + * handle keys with a length. + */ + strbuf_reset(&wtname_buf); + strbuf_add(&wtname_buf, wtname, wtname_len); + + /* + * There is an edge case here: when the worktree references the + * current worktree, then we set up the stack once via + * `worktree_stacks` and once via `worktree_stack`. This is + * wasteful, but in the reading case it shouldn't matter. And + * in the writing case we would notice that the stack is locked + * already and error out when trying to write a reference via + * both stacks. + */ + stack = strmap_get(&store->worktree_stacks, wtname_buf.buf); + if (!stack) { + strbuf_addf(&wt_dir, "%s/worktrees/%s/reftable", + store->base.repo->commondir, wtname_buf.buf); + + store->err = reftable_new_stack(&stack, wt_dir.buf, + store->write_options); + assert(store->err != REFTABLE_API_ERROR); + strmap_put(&store->worktree_stacks, wtname_buf.buf, stack); + } + + strbuf_release(&wt_dir); + return stack; + } + case REF_WORKTREE_CURRENT: + /* + * If there is no worktree stack then we're currently in the + * main worktree. We thus return the main stack in that case. + */ + if (!store->worktree_stack) + return store->main_stack; + return store->worktree_stack; + case REF_WORKTREE_MAIN: + case REF_WORKTREE_SHARED: + return store->main_stack; + default: + BUG("unhandled worktree reference type"); + } +} + +static int should_write_log(struct ref_store *refs, const char *refname) +{ + if (log_all_ref_updates == LOG_REFS_UNSET) + log_all_ref_updates = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; + + switch (log_all_ref_updates) { + case LOG_REFS_NONE: + return refs_reflog_exists(refs, refname); + case LOG_REFS_ALWAYS: + return 1; + case LOG_REFS_NORMAL: + if (should_autocreate_reflog(refname)) + return 1; + return refs_reflog_exists(refs, refname); + default: + BUG("unhandled core.logAllRefUpdates value %d", log_all_ref_updates); + } +} + +static void clear_reftable_log_record(struct reftable_log_record *log) +{ + switch (log->value_type) { + case REFTABLE_LOG_UPDATE: + /* + * When we write log records, the hashes are owned by the + * caller and thus shouldn't be free'd. + */ + log->value.update.old_hash = NULL; + log->value.update.new_hash = NULL; + break; + case REFTABLE_LOG_DELETION: + break; + } + reftable_log_record_release(log); +} + +static void fill_reftable_log_record(struct reftable_log_record *log) +{ + const char *info = git_committer_info(0); + struct ident_split split = {0}; + int sign = 1; + + if (split_ident_line(&split, info, strlen(info))) + BUG("failed splitting committer info"); + + reftable_log_record_release(log); + log->value_type = REFTABLE_LOG_UPDATE; + log->value.update.name = + xstrndup(split.name_begin, split.name_end - split.name_begin); + log->value.update.email = + xstrndup(split.mail_begin, split.mail_end - split.mail_begin); + log->value.update.time = atol(split.date_begin); + if (*split.tz_begin == '-') { + sign = -1; + split.tz_begin++; + } + if (*split.tz_begin == '+') { + sign = 1; + split.tz_begin++; + } + + log->value.update.tz_offset = sign * atoi(split.tz_begin); +} + +static int read_ref_without_reload(struct reftable_stack *stack, + const char *refname, + struct object_id *oid, + struct strbuf *referent, + unsigned int *type) +{ + struct reftable_ref_record ref = {0}; + int ret; + + ret = reftable_stack_read_ref(stack, refname, &ref); + if (ret) + goto done; + + if (ref.value_type == REFTABLE_REF_SYMREF) { + strbuf_reset(referent); + strbuf_addstr(referent, ref.value.symref); + *type |= REF_ISSYMREF; + } else if (reftable_ref_record_val1(&ref)) { + oidread(oid, reftable_ref_record_val1(&ref)); + } else { + /* We got a tombstone, which should not happen. */ + BUG("unhandled reference value type %d", ref.value_type); + } + +done: + assert(ret != REFTABLE_API_ERROR); + reftable_ref_record_release(&ref); + return ret; +} + +static struct ref_store *reftable_be_init(struct repository *repo, + const char *gitdir, + unsigned int store_flags) +{ + struct reftable_ref_store *refs = xcalloc(1, sizeof(*refs)); + struct strbuf path = STRBUF_INIT; + int is_worktree; + mode_t mask; + + mask = umask(0); + umask(mask); + + base_ref_store_init(&refs->base, repo, gitdir, &refs_be_reftable); + strmap_init(&refs->worktree_stacks); + refs->store_flags = store_flags; + refs->write_options.block_size = 4096; + refs->write_options.hash_id = repo->hash_algo->format_id; + refs->write_options.default_permissions = calc_shared_perm(0666 & ~mask); + + /* + * Set up the main reftable stack that is hosted in GIT_COMMON_DIR. + * This stack contains both the shared and the main worktree refs. + * + * Note that we don't try to resolve the path in case we have a + * worktree because `get_common_dir_noenv()` already does it for us. + */ + is_worktree = get_common_dir_noenv(&path, gitdir); + if (!is_worktree) { + strbuf_reset(&path); + strbuf_realpath(&path, gitdir, 0); + } + strbuf_addstr(&path, "/reftable"); + refs->err = reftable_new_stack(&refs->main_stack, path.buf, + refs->write_options); + if (refs->err) + goto done; + + /* + * If we're in a worktree we also need to set up the worktree reftable + * stack that is contained in the per-worktree GIT_DIR. + * + * Ideally, we would also add the stack to our worktree stack map. But + * we have no way to figure out the worktree name here and thus can't + * do it efficiently. + */ + if (is_worktree) { + strbuf_reset(&path); + strbuf_addf(&path, "%s/reftable", gitdir); + + refs->err = reftable_new_stack(&refs->worktree_stack, path.buf, + refs->write_options); + if (refs->err) + goto done; + } + + chdir_notify_reparent("reftables-backend $GIT_DIR", &refs->base.gitdir); + +done: + assert(refs->err != REFTABLE_API_ERROR); + strbuf_release(&path); + return &refs->base; +} + +static int reftable_be_init_db(struct ref_store *ref_store, + int flags UNUSED, + struct strbuf *err UNUSED) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE, "init_db"); + struct strbuf sb = STRBUF_INIT; + + strbuf_addf(&sb, "%s/reftable", refs->base.gitdir); + safe_create_dir(sb.buf, 1); + strbuf_reset(&sb); + + strbuf_addf(&sb, "%s/HEAD", refs->base.gitdir); + write_file(sb.buf, "ref: refs/heads/.invalid"); + adjust_shared_perm(sb.buf); + strbuf_reset(&sb); + + strbuf_addf(&sb, "%s/refs", refs->base.gitdir); + safe_create_dir(sb.buf, 1); + strbuf_reset(&sb); + + strbuf_addf(&sb, "%s/refs/heads", refs->base.gitdir); + write_file(sb.buf, "this repository uses the reftable format"); + adjust_shared_perm(sb.buf); + + strbuf_release(&sb); + return 0; +} + +struct reftable_ref_iterator { + struct ref_iterator base; + struct reftable_ref_store *refs; + struct reftable_iterator iter; + struct reftable_ref_record ref; + struct object_id oid; + + const char *prefix; + unsigned int flags; + int err; +}; + +static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) +{ + struct reftable_ref_iterator *iter = + (struct reftable_ref_iterator *)ref_iterator; + struct reftable_ref_store *refs = iter->refs; + + while (!iter->err) { + int flags = 0; + + iter->err = reftable_iterator_next_ref(&iter->iter, &iter->ref); + if (iter->err) + break; + + /* + * The files backend only lists references contained in "refs/" unless + * the root refs are to be included. We emulate the same behaviour here. + */ + if (!starts_with(iter->ref.refname, "refs/") && + !(iter->flags & DO_FOR_EACH_INCLUDE_ROOT_REFS && + (is_pseudoref(&iter->refs->base, iter->ref.refname) || + is_headref(&iter->refs->base, iter->ref.refname)))) { + continue; + } + + if (iter->prefix && + strncmp(iter->prefix, iter->ref.refname, strlen(iter->prefix))) { + iter->err = 1; + break; + } + + if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY && + parse_worktree_ref(iter->ref.refname, NULL, NULL, NULL) != + REF_WORKTREE_CURRENT) + continue; + + switch (iter->ref.value_type) { + case REFTABLE_REF_VAL1: + oidread(&iter->oid, iter->ref.value.val1); + break; + case REFTABLE_REF_VAL2: + oidread(&iter->oid, iter->ref.value.val2.value); + break; + case REFTABLE_REF_SYMREF: + if (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname, + RESOLVE_REF_READING, &iter->oid, &flags)) + oidclr(&iter->oid); + break; + default: + BUG("unhandled reference value type %d", iter->ref.value_type); + } + + if (is_null_oid(&iter->oid)) + flags |= REF_ISBROKEN; + + if (check_refname_format(iter->ref.refname, REFNAME_ALLOW_ONELEVEL)) { + if (!refname_is_safe(iter->ref.refname)) + die(_("refname is dangerous: %s"), iter->ref.refname); + oidclr(&iter->oid); + flags |= REF_BAD_NAME | REF_ISBROKEN; + } + + if (iter->flags & DO_FOR_EACH_OMIT_DANGLING_SYMREFS && + flags & REF_ISSYMREF && + flags & REF_ISBROKEN) + continue; + + if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) && + !ref_resolves_to_object(iter->ref.refname, refs->base.repo, + &iter->oid, flags)) + continue; + + iter->base.refname = iter->ref.refname; + iter->base.oid = &iter->oid; + iter->base.flags = flags; + + break; + } + + if (iter->err > 0) { + if (ref_iterator_abort(ref_iterator) != ITER_DONE) + return ITER_ERROR; + return ITER_DONE; + } + + if (iter->err < 0) { + ref_iterator_abort(ref_iterator); + return ITER_ERROR; + } + + return ITER_OK; +} + +static int reftable_ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + struct reftable_ref_iterator *iter = + (struct reftable_ref_iterator *)ref_iterator; + + if (iter->ref.value_type == REFTABLE_REF_VAL2) { + oidread(peeled, iter->ref.value.val2.target_value); + return 0; + } + + return -1; +} + +static int reftable_ref_iterator_abort(struct ref_iterator *ref_iterator) +{ + struct reftable_ref_iterator *iter = + (struct reftable_ref_iterator *)ref_iterator; + reftable_ref_record_release(&iter->ref); + reftable_iterator_destroy(&iter->iter); + free(iter); + return ITER_DONE; +} + +static struct ref_iterator_vtable reftable_ref_iterator_vtable = { + .advance = reftable_ref_iterator_advance, + .peel = reftable_ref_iterator_peel, + .abort = reftable_ref_iterator_abort +}; + +static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_store *refs, + struct reftable_stack *stack, + const char *prefix, + int flags) +{ + struct reftable_merged_table *merged_table; + struct reftable_ref_iterator *iter; + int ret; + + iter = xcalloc(1, sizeof(*iter)); + base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable); + iter->prefix = prefix; + iter->base.oid = &iter->oid; + iter->flags = flags; + iter->refs = refs; + + ret = refs->err; + if (ret) + goto done; + + ret = reftable_stack_reload(stack); + if (ret) + goto done; + + merged_table = reftable_stack_merged_table(stack); + + ret = reftable_merged_table_seek_ref(merged_table, &iter->iter, prefix); + if (ret) + goto done; + +done: + iter->err = ret; + return iter; +} + +static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_store, + const char *prefix, + const char **exclude_patterns, + unsigned int flags) +{ + struct reftable_ref_iterator *main_iter, *worktree_iter; + struct reftable_ref_store *refs; + unsigned int required_flags = REF_STORE_READ; + + if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) + required_flags |= REF_STORE_ODB; + refs = reftable_be_downcast(ref_store, required_flags, "ref_iterator_begin"); + + main_iter = ref_iterator_for_stack(refs, refs->main_stack, prefix, flags); + + /* + * The worktree stack is only set when we're in an actual worktree + * right now. If we aren't, then we return the common reftable + * iterator, only. + */ + if (!refs->worktree_stack) + return &main_iter->base; + + /* + * Otherwise we merge both the common and the per-worktree refs into a + * single iterator. + */ + worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, flags); + return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, + ref_iterator_select, NULL); +} + +static int reftable_be_read_raw_ref(struct ref_store *ref_store, + const char *refname, + struct object_id *oid, + struct strbuf *referent, + unsigned int *type, + int *failure_errno) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_READ, "read_raw_ref"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + int ret; + + if (refs->err < 0) + return refs->err; + + ret = reftable_stack_reload(stack); + if (ret) + return ret; + + ret = read_ref_without_reload(stack, refname, oid, referent, type); + if (ret < 0) + return ret; + if (ret > 0) { + *failure_errno = ENOENT; + return -1; + } + + return 0; +} + +static int reftable_be_read_symbolic_ref(struct ref_store *ref_store, + const char *refname, + struct strbuf *referent) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_READ, "read_symbolic_ref"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_ref_record ref = {0}; + int ret; + + ret = reftable_stack_reload(stack); + if (ret) + return ret; + + ret = reftable_stack_read_ref(stack, refname, &ref); + if (ret == 0 && ref.value_type == REFTABLE_REF_SYMREF) + strbuf_addstr(referent, ref.value.symref); + else + ret = -1; + + reftable_ref_record_release(&ref); + return ret; +} + +/* + * Return the refname under which update was originally requested. + */ +static const char *original_update_refname(struct ref_update *update) +{ + while (update->parent_update) + update = update->parent_update; + return update->refname; +} + +struct reftable_transaction_update { + struct ref_update *update; + struct object_id current_oid; +}; + +struct write_transaction_table_arg { + struct reftable_ref_store *refs; + struct reftable_stack *stack; + struct reftable_addition *addition; + struct reftable_transaction_update *updates; + size_t updates_nr; + size_t updates_alloc; + size_t updates_expected; +}; + +struct reftable_transaction_data { + struct write_transaction_table_arg *args; + size_t args_nr, args_alloc; +}; + +static void free_transaction_data(struct reftable_transaction_data *tx_data) +{ + if (!tx_data) + return; + for (size_t i = 0; i < tx_data->args_nr; i++) { + reftable_addition_destroy(tx_data->args[i].addition); + free(tx_data->args[i].updates); + } + free(tx_data->args); + free(tx_data); +} + +/* + * Prepare transaction update for the given reference update. This will cause + * us to lock the corresponding reftable stack for concurrent modification. + */ +static int prepare_transaction_update(struct write_transaction_table_arg **out, + struct reftable_ref_store *refs, + struct reftable_transaction_data *tx_data, + struct ref_update *update, + struct strbuf *err) +{ + struct reftable_stack *stack = stack_for(refs, update->refname, NULL); + struct write_transaction_table_arg *arg = NULL; + size_t i; + int ret; + + /* + * Search for a preexisting stack update. If there is one then we add + * the update to it, otherwise we set up a new stack update. + */ + for (i = 0; !arg && i < tx_data->args_nr; i++) + if (tx_data->args[i].stack == stack) + arg = &tx_data->args[i]; + + if (!arg) { + struct reftable_addition *addition; + + ret = reftable_stack_reload(stack); + if (ret) + return ret; + + ret = reftable_stack_new_addition(&addition, stack); + if (ret) { + if (ret == REFTABLE_LOCK_ERROR) + strbuf_addstr(err, "cannot lock references"); + return ret; + } + + ALLOC_GROW(tx_data->args, tx_data->args_nr + 1, + tx_data->args_alloc); + arg = &tx_data->args[tx_data->args_nr++]; + arg->refs = refs; + arg->stack = stack; + arg->addition = addition; + arg->updates = NULL; + arg->updates_nr = 0; + arg->updates_alloc = 0; + arg->updates_expected = 0; + } + + arg->updates_expected++; + + if (out) + *out = arg; + + return 0; +} + +/* + * Queue a reference update for the correct stack. We potentially need to + * handle multiple stack updates in a single transaction when it spans across + * multiple worktrees. + */ +static int queue_transaction_update(struct reftable_ref_store *refs, + struct reftable_transaction_data *tx_data, + struct ref_update *update, + struct object_id *current_oid, + struct strbuf *err) +{ + struct write_transaction_table_arg *arg = NULL; + int ret; + + if (update->backend_data) + BUG("reference update queued more than once"); + + ret = prepare_transaction_update(&arg, refs, tx_data, update, err); + if (ret < 0) + return ret; + + ALLOC_GROW(arg->updates, arg->updates_nr + 1, + arg->updates_alloc); + arg->updates[arg->updates_nr].update = update; + oidcpy(&arg->updates[arg->updates_nr].current_oid, current_oid); + update->backend_data = &arg->updates[arg->updates_nr++]; + + return 0; +} + +static int reftable_be_transaction_prepare(struct ref_store *ref_store, + struct ref_transaction *transaction, + struct strbuf *err) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE|REF_STORE_MAIN, "ref_transaction_prepare"); + struct strbuf referent = STRBUF_INIT, head_referent = STRBUF_INIT; + struct string_list affected_refnames = STRING_LIST_INIT_NODUP; + struct reftable_transaction_data *tx_data = NULL; + struct object_id head_oid; + unsigned int head_type = 0; + size_t i; + int ret; + + ret = refs->err; + if (ret < 0) + goto done; + + tx_data = xcalloc(1, sizeof(*tx_data)); + + /* + * Preprocess all updates. For one we check that there are no duplicate + * reference updates in this transaction. Second, we lock all stacks + * that will be modified during the transaction. + */ + for (i = 0; i < transaction->nr; i++) { + ret = prepare_transaction_update(NULL, refs, tx_data, + transaction->updates[i], err); + if (ret) + goto done; + + string_list_append(&affected_refnames, + transaction->updates[i]->refname); + } + + /* + * Now that we have counted updates per stack we can preallocate their + * arrays. This avoids having to reallocate many times. + */ + for (i = 0; i < tx_data->args_nr; i++) { + CALLOC_ARRAY(tx_data->args[i].updates, tx_data->args[i].updates_expected); + tx_data->args[i].updates_alloc = tx_data->args[i].updates_expected; + } + + /* + * Fail if a refname appears more than once in the transaction. + * This code is taken from the files backend and is a good candidate to + * be moved into the generic layer. + */ + string_list_sort(&affected_refnames); + if (ref_update_reject_duplicates(&affected_refnames, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto done; + } + + ret = read_ref_without_reload(stack_for(refs, "HEAD", NULL), "HEAD", &head_oid, + &head_referent, &head_type); + if (ret < 0) + goto done; + + for (i = 0; i < transaction->nr; i++) { + struct ref_update *u = transaction->updates[i]; + struct object_id current_oid = {0}; + struct reftable_stack *stack; + const char *rewritten_ref; + + stack = stack_for(refs, u->refname, &rewritten_ref); + + /* Verify that the new object ID is valid. */ + if ((u->flags & REF_HAVE_NEW) && !is_null_oid(&u->new_oid) && + !(u->flags & REF_SKIP_OID_VERIFICATION) && + !(u->flags & REF_LOG_ONLY)) { + struct object *o = parse_object(refs->base.repo, &u->new_oid); + if (!o) { + strbuf_addf(err, + _("trying to write ref '%s' with nonexistent object %s"), + u->refname, oid_to_hex(&u->new_oid)); + ret = -1; + goto done; + } + + if (o->type != OBJ_COMMIT && is_branch(u->refname)) { + strbuf_addf(err, _("trying to write non-commit object %s to branch '%s'"), + oid_to_hex(&u->new_oid), u->refname); + ret = -1; + goto done; + } + } + + /* + * When we update the reference that HEAD points to we enqueue + * a second log-only update for HEAD so that its reflog is + * updated accordingly. + */ + if (head_type == REF_ISSYMREF && + !(u->flags & REF_LOG_ONLY) && + !(u->flags & REF_UPDATE_VIA_HEAD) && + !strcmp(rewritten_ref, head_referent.buf)) { + struct ref_update *new_update; + + /* + * First make sure that HEAD is not already in the + * transaction. This check is O(lg N) in the transaction + * size, but it happens at most once per transaction. + */ + if (string_list_has_string(&affected_refnames, "HEAD")) { + /* An entry already existed */ + strbuf_addf(err, + _("multiple updates for 'HEAD' (including one " + "via its referent '%s') are not allowed"), + u->refname); + ret = TRANSACTION_NAME_CONFLICT; + goto done; + } + + new_update = ref_transaction_add_update( + transaction, "HEAD", + u->flags | REF_LOG_ONLY | REF_NO_DEREF, + &u->new_oid, &u->old_oid, u->msg); + string_list_insert(&affected_refnames, new_update->refname); + } + + ret = read_ref_without_reload(stack, rewritten_ref, + ¤t_oid, &referent, &u->type); + if (ret < 0) + goto done; + if (ret > 0 && (!(u->flags & REF_HAVE_OLD) || is_null_oid(&u->old_oid))) { + /* + * The reference does not exist, and we either have no + * old object ID or expect the reference to not exist. + * We can thus skip below safety checks as well as the + * symref splitting. But we do want to verify that + * there is no conflicting reference here so that we + * can output a proper error message instead of failing + * at a later point. + */ + ret = refs_verify_refname_available(ref_store, u->refname, + &affected_refnames, NULL, err); + if (ret < 0) + goto done; + + /* + * There is no need to write the reference deletion + * when the reference in question doesn't exist. + */ + if (u->flags & REF_HAVE_NEW && !is_null_oid(&u->new_oid)) { + ret = queue_transaction_update(refs, tx_data, u, + ¤t_oid, err); + if (ret) + goto done; + } + + continue; + } + if (ret > 0) { + /* The reference does not exist, but we expected it to. */ + strbuf_addf(err, _("cannot lock ref '%s': " + "unable to resolve reference '%s'"), + original_update_refname(u), u->refname); + ret = -1; + goto done; + } + + if (u->type & REF_ISSYMREF) { + /* + * The reftable stack is locked at this point already, + * so it is safe to call `refs_resolve_ref_unsafe()` + * here without causing races. + */ + const char *resolved = refs_resolve_ref_unsafe(&refs->base, u->refname, 0, + ¤t_oid, NULL); + + if (u->flags & REF_NO_DEREF) { + if (u->flags & REF_HAVE_OLD && !resolved) { + strbuf_addf(err, _("cannot lock ref '%s': " + "error reading reference"), u->refname); + ret = -1; + goto done; + } + } else { + struct ref_update *new_update; + int new_flags; + + new_flags = u->flags; + if (!strcmp(rewritten_ref, "HEAD")) + new_flags |= REF_UPDATE_VIA_HEAD; + + /* + * If we are updating a symref (eg. HEAD), we should also + * update the branch that the symref points to. + * + * This is generic functionality, and would be better + * done in refs.c, but the current implementation is + * intertwined with the locking in files-backend.c. + */ + new_update = ref_transaction_add_update( + transaction, referent.buf, new_flags, + &u->new_oid, &u->old_oid, u->msg); + new_update->parent_update = u; + + /* + * Change the symbolic ref update to log only. Also, it + * doesn't need to check its old OID value, as that will be + * done when new_update is processed. + */ + u->flags |= REF_LOG_ONLY | REF_NO_DEREF; + u->flags &= ~REF_HAVE_OLD; + + if (string_list_has_string(&affected_refnames, new_update->refname)) { + strbuf_addf(err, + _("multiple updates for '%s' (including one " + "via symref '%s') are not allowed"), + referent.buf, u->refname); + ret = TRANSACTION_NAME_CONFLICT; + goto done; + } + string_list_insert(&affected_refnames, new_update->refname); + } + } + + /* + * Verify that the old object matches our expectations. Note + * that the error messages here do not make a lot of sense in + * the context of the reftable backend as we never lock + * individual refs. But the error messages match what the files + * backend returns, which keeps our tests happy. + */ + if (u->flags & REF_HAVE_OLD && !oideq(¤t_oid, &u->old_oid)) { + if (is_null_oid(&u->old_oid)) + strbuf_addf(err, _("cannot lock ref '%s': " + "reference already exists"), + original_update_refname(u)); + else if (is_null_oid(¤t_oid)) + strbuf_addf(err, _("cannot lock ref '%s': " + "reference is missing but expected %s"), + original_update_refname(u), + oid_to_hex(&u->old_oid)); + else + strbuf_addf(err, _("cannot lock ref '%s': " + "is at %s but expected %s"), + original_update_refname(u), + oid_to_hex(¤t_oid), + oid_to_hex(&u->old_oid)); + ret = -1; + goto done; + } + + /* + * If all of the following conditions are true: + * + * - We're not about to write a symref. + * - We're not about to write a log-only entry. + * - Old and new object ID are different. + * + * Then we're essentially doing a no-op update that can be + * skipped. This is not only for the sake of efficiency, but + * also skips writing unneeded reflog entries. + */ + if ((u->type & REF_ISSYMREF) || + (u->flags & REF_LOG_ONLY) || + (u->flags & REF_HAVE_NEW && !oideq(¤t_oid, &u->new_oid))) { + ret = queue_transaction_update(refs, tx_data, u, + ¤t_oid, err); + if (ret) + goto done; + } + } + + transaction->backend_data = tx_data; + transaction->state = REF_TRANSACTION_PREPARED; + +done: + assert(ret != REFTABLE_API_ERROR); + if (ret < 0) { + free_transaction_data(tx_data); + transaction->state = REF_TRANSACTION_CLOSED; + if (!err->len) + strbuf_addf(err, _("reftable: transaction prepare: %s"), + reftable_error_str(ret)); + } + string_list_clear(&affected_refnames, 0); + strbuf_release(&referent); + strbuf_release(&head_referent); + + return ret; +} + +static int reftable_be_transaction_abort(struct ref_store *ref_store, + struct ref_transaction *transaction, + struct strbuf *err) +{ + struct reftable_transaction_data *tx_data = transaction->backend_data; + free_transaction_data(tx_data); + transaction->state = REF_TRANSACTION_CLOSED; + return 0; +} + +static int transaction_update_cmp(const void *a, const void *b) +{ + return strcmp(((struct reftable_transaction_update *)a)->update->refname, + ((struct reftable_transaction_update *)b)->update->refname); +} + +static int write_transaction_table(struct reftable_writer *writer, void *cb_data) +{ + struct write_transaction_table_arg *arg = cb_data; + struct reftable_merged_table *mt = + reftable_stack_merged_table(arg->stack); + uint64_t ts = reftable_stack_next_update_index(arg->stack); + struct reftable_log_record *logs = NULL; + size_t logs_nr = 0, logs_alloc = 0, i; + int ret = 0; + + QSORT(arg->updates, arg->updates_nr, transaction_update_cmp); + + reftable_writer_set_limits(writer, ts, ts); + + for (i = 0; i < arg->updates_nr; i++) { + struct reftable_transaction_update *tx_update = &arg->updates[i]; + struct ref_update *u = tx_update->update; + + /* + * Write a reflog entry when updating a ref to point to + * something new in either of the following cases: + * + * - The reference is about to be deleted. We always want to + * delete the reflog in that case. + * - REF_FORCE_CREATE_REFLOG is set, asking us to always create + * the reflog entry. + * - `core.logAllRefUpdates` tells us to create the reflog for + * the given ref. + */ + if (u->flags & REF_HAVE_NEW && !(u->type & REF_ISSYMREF) && is_null_oid(&u->new_oid)) { + struct reftable_log_record log = {0}; + struct reftable_iterator it = {0}; + + /* + * When deleting refs we also delete all reflog entries + * with them. While it is not strictly required to + * delete reflogs together with their refs, this + * matches the behaviour of the files backend. + * + * Unfortunately, we have no better way than to delete + * all reflog entries one by one. + */ + ret = reftable_merged_table_seek_log(mt, &it, u->refname); + while (ret == 0) { + struct reftable_log_record *tombstone; + + ret = reftable_iterator_next_log(&it, &log); + if (ret < 0) + break; + if (ret > 0 || strcmp(log.refname, u->refname)) { + ret = 0; + break; + } + + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + tombstone = &logs[logs_nr++]; + tombstone->refname = xstrdup(u->refname); + tombstone->value_type = REFTABLE_LOG_DELETION; + tombstone->update_index = log.update_index; + } + + reftable_log_record_release(&log); + reftable_iterator_destroy(&it); + + if (ret) + goto done; + } else if (u->flags & REF_HAVE_NEW && + (u->flags & REF_FORCE_CREATE_REFLOG || + should_write_log(&arg->refs->base, u->refname))) { + struct reftable_log_record *log; + + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + log = &logs[logs_nr++]; + memset(log, 0, sizeof(*log)); + + fill_reftable_log_record(log); + log->update_index = ts; + log->refname = xstrdup(u->refname); + log->value.update.new_hash = u->new_oid.hash; + log->value.update.old_hash = tx_update->current_oid.hash; + log->value.update.message = + xstrndup(u->msg, arg->refs->write_options.block_size / 2); + } + + if (u->flags & REF_LOG_ONLY) + continue; + + if (u->flags & REF_HAVE_NEW && is_null_oid(&u->new_oid)) { + struct reftable_ref_record ref = { + .refname = (char *)u->refname, + .update_index = ts, + .value_type = REFTABLE_REF_DELETION, + }; + + ret = reftable_writer_add_ref(writer, &ref); + if (ret < 0) + goto done; + } else if (u->flags & REF_HAVE_NEW) { + struct reftable_ref_record ref = {0}; + struct object_id peeled; + int peel_error; + + ref.refname = (char *)u->refname; + ref.update_index = ts; + + peel_error = peel_object(&u->new_oid, &peeled); + if (!peel_error) { + ref.value_type = REFTABLE_REF_VAL2; + memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ); + memcpy(ref.value.val2.value, u->new_oid.hash, GIT_MAX_RAWSZ); + } else if (!is_null_oid(&u->new_oid)) { + ref.value_type = REFTABLE_REF_VAL1; + memcpy(ref.value.val1, u->new_oid.hash, GIT_MAX_RAWSZ); + } + + ret = reftable_writer_add_ref(writer, &ref); + if (ret < 0) + goto done; + } + } + + /* + * Logs are written at the end so that we do not have intermixed ref + * and log blocks. + */ + if (logs) { + ret = reftable_writer_add_logs(writer, logs, logs_nr); + if (ret < 0) + goto done; + } + +done: + assert(ret != REFTABLE_API_ERROR); + for (i = 0; i < logs_nr; i++) + clear_reftable_log_record(&logs[i]); + free(logs); + return ret; +} + +static int reftable_be_transaction_finish(struct ref_store *ref_store, + struct ref_transaction *transaction, + struct strbuf *err) +{ + struct reftable_transaction_data *tx_data = transaction->backend_data; + int ret = 0; + + for (size_t i = 0; i < tx_data->args_nr; i++) { + ret = reftable_addition_add(tx_data->args[i].addition, + write_transaction_table, &tx_data->args[i]); + if (ret < 0) + goto done; + + ret = reftable_addition_commit(tx_data->args[i].addition); + if (ret < 0) + goto done; + } + +done: + assert(ret != REFTABLE_API_ERROR); + free_transaction_data(tx_data); + transaction->state = REF_TRANSACTION_CLOSED; + + if (ret) { + strbuf_addf(err, _("reftable: transaction failure: %s"), + reftable_error_str(ret)); + return -1; + } + return ret; +} + +static int reftable_be_initial_transaction_commit(struct ref_store *ref_store UNUSED, + struct ref_transaction *transaction, + struct strbuf *err) +{ + return ref_transaction_commit(transaction, err); +} + +static int reftable_be_pack_refs(struct ref_store *ref_store, + struct pack_refs_opts *opts) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE | REF_STORE_ODB, "pack_refs"); + struct reftable_stack *stack; + int ret; + + if (refs->err) + return refs->err; + + stack = refs->worktree_stack; + if (!stack) + stack = refs->main_stack; + + ret = reftable_stack_compact_all(stack, NULL); + if (ret) + goto out; + ret = reftable_stack_clean(stack); + if (ret) + goto out; + +out: + return ret; +} + +struct write_create_symref_arg { + struct reftable_ref_store *refs; + struct reftable_stack *stack; + const char *refname; + const char *target; + const char *logmsg; +}; + +static int write_create_symref_table(struct reftable_writer *writer, void *cb_data) +{ + struct write_create_symref_arg *create = cb_data; + uint64_t ts = reftable_stack_next_update_index(create->stack); + struct reftable_ref_record ref = { + .refname = (char *)create->refname, + .value_type = REFTABLE_REF_SYMREF, + .value.symref = (char *)create->target, + .update_index = ts, + }; + struct reftable_log_record log = {0}; + struct object_id new_oid; + struct object_id old_oid; + int ret; + + reftable_writer_set_limits(writer, ts, ts); + + ret = reftable_writer_add_ref(writer, &ref); + if (ret) + return ret; + + /* + * Note that it is important to try and resolve the reference before we + * write the log entry. This is because `should_write_log()` will munge + * `core.logAllRefUpdates`, which is undesirable when we create a new + * repository because it would be written into the config. As HEAD will + * not resolve for new repositories this ordering will ensure that this + * never happens. + */ + if (!create->logmsg || + !refs_resolve_ref_unsafe(&create->refs->base, create->target, + RESOLVE_REF_READING, &new_oid, NULL) || + !should_write_log(&create->refs->base, create->refname)) + return 0; + + fill_reftable_log_record(&log); + log.refname = xstrdup(create->refname); + log.update_index = ts; + log.value.update.message = xstrndup(create->logmsg, + create->refs->write_options.block_size / 2); + log.value.update.new_hash = new_oid.hash; + if (refs_resolve_ref_unsafe(&create->refs->base, create->refname, + RESOLVE_REF_READING, &old_oid, NULL)) + log.value.update.old_hash = old_oid.hash; + + ret = reftable_writer_add_log(writer, &log); + clear_reftable_log_record(&log); + return ret; +} + +static int reftable_be_create_symref(struct ref_store *ref_store, + const char *refname, + const char *target, + const char *logmsg) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE, "create_symref"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct write_create_symref_arg arg = { + .refs = refs, + .stack = stack, + .refname = refname, + .target = target, + .logmsg = logmsg, + }; + int ret; + + ret = refs->err; + if (ret < 0) + goto done; + + ret = reftable_stack_reload(stack); + if (ret) + goto done; + + ret = reftable_stack_add(stack, &write_create_symref_table, &arg); + +done: + assert(ret != REFTABLE_API_ERROR); + if (ret) + error("unable to write symref for %s: %s", refname, + reftable_error_str(ret)); + return ret; +} + +struct write_copy_arg { + struct reftable_ref_store *refs; + struct reftable_stack *stack; + const char *oldname; + const char *newname; + const char *logmsg; + int delete_old; +}; + +static int write_copy_table(struct reftable_writer *writer, void *cb_data) +{ + struct write_copy_arg *arg = cb_data; + uint64_t deletion_ts, creation_ts; + struct reftable_merged_table *mt = reftable_stack_merged_table(arg->stack); + struct reftable_ref_record old_ref = {0}, refs[2] = {0}; + struct reftable_log_record old_log = {0}, *logs = NULL; + struct reftable_iterator it = {0}; + struct string_list skip = STRING_LIST_INIT_NODUP; + struct strbuf errbuf = STRBUF_INIT; + size_t logs_nr = 0, logs_alloc = 0, i; + int ret; + + if (reftable_stack_read_ref(arg->stack, arg->oldname, &old_ref)) { + ret = error(_("refname %s not found"), arg->oldname); + goto done; + } + if (old_ref.value_type == REFTABLE_REF_SYMREF) { + ret = error(_("refname %s is a symbolic ref, copying it is not supported"), + arg->oldname); + goto done; + } + + /* + * There's nothing to do in case the old and new name are the same, so + * we exit early in that case. + */ + if (!strcmp(arg->oldname, arg->newname)) { + ret = 0; + goto done; + } + + /* + * Verify that the new refname is available. + */ + string_list_insert(&skip, arg->oldname); + ret = refs_verify_refname_available(&arg->refs->base, arg->newname, + NULL, &skip, &errbuf); + if (ret < 0) { + error("%s", errbuf.buf); + goto done; + } + + /* + * When deleting the old reference we have to use two update indices: + * once to delete the old ref and its reflog, and once to create the + * new ref and its reflog. They need to be staged with two separate + * indices because the new reflog needs to encode both the deletion of + * the old branch and the creation of the new branch, and we cannot do + * two changes to a reflog in a single update. + */ + deletion_ts = creation_ts = reftable_stack_next_update_index(arg->stack); + if (arg->delete_old) + creation_ts++; + reftable_writer_set_limits(writer, deletion_ts, creation_ts); + + /* + * Add the new reference. If this is a rename then we also delete the + * old reference. + */ + refs[0] = old_ref; + refs[0].refname = (char *)arg->newname; + refs[0].update_index = creation_ts; + if (arg->delete_old) { + refs[1].refname = (char *)arg->oldname; + refs[1].value_type = REFTABLE_REF_DELETION; + refs[1].update_index = deletion_ts; + } + ret = reftable_writer_add_refs(writer, refs, arg->delete_old ? 2 : 1); + if (ret < 0) + goto done; + + /* + * When deleting the old branch we need to create a reflog entry on the + * new branch name that indicates that the old branch has been deleted + * and then recreated. This is a tad weird, but matches what the files + * backend does. + */ + if (arg->delete_old) { + struct strbuf head_referent = STRBUF_INIT; + struct object_id head_oid; + int append_head_reflog; + unsigned head_type = 0; + + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + memset(&logs[logs_nr], 0, sizeof(logs[logs_nr])); + fill_reftable_log_record(&logs[logs_nr]); + logs[logs_nr].refname = (char *)arg->newname; + logs[logs_nr].update_index = deletion_ts; + logs[logs_nr].value.update.message = + xstrndup(arg->logmsg, arg->refs->write_options.block_size / 2); + logs[logs_nr].value.update.old_hash = old_ref.value.val1; + logs_nr++; + + ret = read_ref_without_reload(arg->stack, "HEAD", &head_oid, &head_referent, &head_type); + if (ret < 0) + goto done; + append_head_reflog = (head_type & REF_ISSYMREF) && !strcmp(head_referent.buf, arg->oldname); + strbuf_release(&head_referent); + + /* + * The files backend uses `refs_delete_ref()` to delete the old + * branch name, which will append a reflog entry for HEAD in + * case it points to the old branch. + */ + if (append_head_reflog) { + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + logs[logs_nr] = logs[logs_nr - 1]; + logs[logs_nr].refname = "HEAD"; + logs_nr++; + } + } + + /* + * Create the reflog entry for the newly created branch. + */ + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + memset(&logs[logs_nr], 0, sizeof(logs[logs_nr])); + fill_reftable_log_record(&logs[logs_nr]); + logs[logs_nr].refname = (char *)arg->newname; + logs[logs_nr].update_index = creation_ts; + logs[logs_nr].value.update.message = + xstrndup(arg->logmsg, arg->refs->write_options.block_size / 2); + logs[logs_nr].value.update.new_hash = old_ref.value.val1; + logs_nr++; + + /* + * In addition to writing the reflog entry for the new branch, we also + * copy over all log entries from the old reflog. Last but not least, + * when renaming we also have to delete all the old reflog entries. + */ + ret = reftable_merged_table_seek_log(mt, &it, arg->oldname); + if (ret < 0) + goto done; + + while (1) { + ret = reftable_iterator_next_log(&it, &old_log); + if (ret < 0) + goto done; + if (ret > 0 || strcmp(old_log.refname, arg->oldname)) { + ret = 0; + break; + } + + free(old_log.refname); + + /* + * Copy over the old reflog entry with the new refname. + */ + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + logs[logs_nr] = old_log; + logs[logs_nr].refname = (char *)arg->newname; + logs_nr++; + + /* + * Delete the old reflog entry in case we are renaming. + */ + if (arg->delete_old) { + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + memset(&logs[logs_nr], 0, sizeof(logs[logs_nr])); + logs[logs_nr].refname = (char *)arg->oldname; + logs[logs_nr].value_type = REFTABLE_LOG_DELETION; + logs[logs_nr].update_index = old_log.update_index; + logs_nr++; + } + + /* + * Transfer ownership of the log record we're iterating over to + * the array of log records. Otherwise, the pointers would get + * free'd or reallocated by the iterator. + */ + memset(&old_log, 0, sizeof(old_log)); + } + + ret = reftable_writer_add_logs(writer, logs, logs_nr); + if (ret < 0) + goto done; + +done: + assert(ret != REFTABLE_API_ERROR); + reftable_iterator_destroy(&it); + string_list_clear(&skip, 0); + strbuf_release(&errbuf); + for (i = 0; i < logs_nr; i++) { + if (!strcmp(logs[i].refname, "HEAD")) + continue; + if (logs[i].value.update.old_hash == old_ref.value.val1) + logs[i].value.update.old_hash = NULL; + if (logs[i].value.update.new_hash == old_ref.value.val1) + logs[i].value.update.new_hash = NULL; + logs[i].refname = NULL; + reftable_log_record_release(&logs[i]); + } + free(logs); + reftable_ref_record_release(&old_ref); + reftable_log_record_release(&old_log); + return ret; +} + +static int reftable_be_rename_ref(struct ref_store *ref_store, + const char *oldrefname, + const char *newrefname, + const char *logmsg) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE, "rename_ref"); + struct reftable_stack *stack = stack_for(refs, newrefname, &newrefname); + struct write_copy_arg arg = { + .refs = refs, + .stack = stack, + .oldname = oldrefname, + .newname = newrefname, + .logmsg = logmsg, + .delete_old = 1, + }; + int ret; + + ret = refs->err; + if (ret < 0) + goto done; + + ret = reftable_stack_reload(stack); + if (ret) + goto done; + ret = reftable_stack_add(stack, &write_copy_table, &arg); + +done: + assert(ret != REFTABLE_API_ERROR); + return ret; +} + +static int reftable_be_copy_ref(struct ref_store *ref_store, + const char *oldrefname, + const char *newrefname, + const char *logmsg) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE, "copy_ref"); + struct reftable_stack *stack = stack_for(refs, newrefname, &newrefname); + struct write_copy_arg arg = { + .refs = refs, + .stack = stack, + .oldname = oldrefname, + .newname = newrefname, + .logmsg = logmsg, + }; + int ret; + + ret = refs->err; + if (ret < 0) + goto done; + + ret = reftable_stack_reload(stack); + if (ret) + goto done; + ret = reftable_stack_add(stack, &write_copy_table, &arg); + +done: + assert(ret != REFTABLE_API_ERROR); + return ret; +} + +struct reftable_reflog_iterator { + struct ref_iterator base; + struct reftable_ref_store *refs; + struct reftable_iterator iter; + struct reftable_log_record log; + char *last_name; + int err; +}; + +static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator) +{ + struct reftable_reflog_iterator *iter = + (struct reftable_reflog_iterator *)ref_iterator; + + while (!iter->err) { + iter->err = reftable_iterator_next_log(&iter->iter, &iter->log); + if (iter->err) + break; + + /* + * We want the refnames that we have reflogs for, so we skip if + * we've already produced this name. This could be faster by + * seeking directly to reflog@update_index==0. + */ + if (iter->last_name && !strcmp(iter->log.refname, iter->last_name)) + continue; + + if (check_refname_format(iter->log.refname, + REFNAME_ALLOW_ONELEVEL)) + continue; + + free(iter->last_name); + iter->last_name = xstrdup(iter->log.refname); + iter->base.refname = iter->log.refname; + + break; + } + + if (iter->err > 0) { + if (ref_iterator_abort(ref_iterator) != ITER_DONE) + return ITER_ERROR; + return ITER_DONE; + } + + if (iter->err < 0) { + ref_iterator_abort(ref_iterator); + return ITER_ERROR; + } + + return ITER_OK; +} + +static int reftable_reflog_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled) +{ + BUG("reftable reflog iterator cannot be peeled"); + return -1; +} + +static int reftable_reflog_iterator_abort(struct ref_iterator *ref_iterator) +{ + struct reftable_reflog_iterator *iter = + (struct reftable_reflog_iterator *)ref_iterator; + reftable_log_record_release(&iter->log); + reftable_iterator_destroy(&iter->iter); + free(iter->last_name); + free(iter); + return ITER_DONE; +} + +static struct ref_iterator_vtable reftable_reflog_iterator_vtable = { + .advance = reftable_reflog_iterator_advance, + .peel = reftable_reflog_iterator_peel, + .abort = reftable_reflog_iterator_abort +}; + +static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftable_ref_store *refs, + struct reftable_stack *stack) +{ + struct reftable_merged_table *merged_table; + struct reftable_reflog_iterator *iter; + int ret; + + iter = xcalloc(1, sizeof(*iter)); + base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable); + iter->refs = refs; + + ret = refs->err; + if (ret) + goto done; + + ret = reftable_stack_reload(refs->main_stack); + if (ret < 0) + goto done; + + merged_table = reftable_stack_merged_table(stack); + + ret = reftable_merged_table_seek_log(merged_table, &iter->iter, ""); + if (ret < 0) + goto done; + +done: + iter->err = ret; + return iter; +} + +static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store *ref_store) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_iterator_begin"); + struct reftable_reflog_iterator *main_iter, *worktree_iter; + + main_iter = reflog_iterator_for_stack(refs, refs->main_stack); + if (!refs->worktree_stack) + return &main_iter->base; + + worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack); + + return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, + ref_iterator_select, NULL); +} + +static int yield_log_record(struct reftable_log_record *log, + each_reflog_ent_fn fn, + void *cb_data) +{ + struct object_id old_oid, new_oid; + const char *full_committer; + + oidread(&old_oid, log->value.update.old_hash); + oidread(&new_oid, log->value.update.new_hash); + + /* + * When both the old object ID and the new object ID are null + * then this is the reflog existence marker. The caller must + * not be aware of it. + */ + if (is_null_oid(&old_oid) && is_null_oid(&new_oid)) + return 0; + + full_committer = fmt_ident(log->value.update.name, log->value.update.email, + WANT_COMMITTER_IDENT, NULL, IDENT_NO_DATE); + return fn(&old_oid, &new_oid, full_committer, + log->value.update.time, log->value.update.tz_offset, + log->value.update.message, cb_data); +} + +static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store, + const char *refname, + each_reflog_ent_fn fn, + void *cb_data) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent_reverse"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_merged_table *mt = NULL; + struct reftable_log_record log = {0}; + struct reftable_iterator it = {0}; + int ret; + + if (refs->err < 0) + return refs->err; + + mt = reftable_stack_merged_table(stack); + ret = reftable_merged_table_seek_log(mt, &it, refname); + while (!ret) { + ret = reftable_iterator_next_log(&it, &log); + if (ret < 0) + break; + if (ret > 0 || strcmp(log.refname, refname)) { + ret = 0; + break; + } + + ret = yield_log_record(&log, fn, cb_data); + if (ret) + break; + } + + reftable_log_record_release(&log); + reftable_iterator_destroy(&it); + return ret; +} + +static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store, + const char *refname, + each_reflog_ent_fn fn, + void *cb_data) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_merged_table *mt = NULL; + struct reftable_log_record *logs = NULL; + struct reftable_iterator it = {0}; + size_t logs_alloc = 0, logs_nr = 0, i; + int ret; + + if (refs->err < 0) + return refs->err; + + mt = reftable_stack_merged_table(stack); + ret = reftable_merged_table_seek_log(mt, &it, refname); + while (!ret) { + struct reftable_log_record log = {0}; + + ret = reftable_iterator_next_log(&it, &log); + if (ret < 0) + goto done; + if (ret > 0 || strcmp(log.refname, refname)) { + reftable_log_record_release(&log); + ret = 0; + break; + } + + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + logs[logs_nr++] = log; + } + + for (i = logs_nr; i--;) { + ret = yield_log_record(&logs[i], fn, cb_data); + if (ret) + goto done; + } + +done: + reftable_iterator_destroy(&it); + for (i = 0; i < logs_nr; i++) + reftable_log_record_release(&logs[i]); + free(logs); + return ret; +} + +static int reftable_be_reflog_exists(struct ref_store *ref_store, + const char *refname) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_exists"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_merged_table *mt = reftable_stack_merged_table(stack); + struct reftable_log_record log = {0}; + struct reftable_iterator it = {0}; + int ret; + + ret = refs->err; + if (ret < 0) + goto done; + + ret = reftable_stack_reload(stack); + if (ret < 0) + goto done; + + ret = reftable_merged_table_seek_log(mt, &it, refname); + if (ret < 0) + goto done; + + /* + * Check whether we get at least one log record for the given ref name. + * If so, the reflog exists, otherwise it doesn't. + */ + ret = reftable_iterator_next_log(&it, &log); + if (ret < 0) + goto done; + if (ret > 0) { + ret = 0; + goto done; + } + + ret = strcmp(log.refname, refname) == 0; + +done: + reftable_iterator_destroy(&it); + reftable_log_record_release(&log); + if (ret < 0) + ret = 0; + return ret; +} + +struct write_reflog_existence_arg { + struct reftable_ref_store *refs; + const char *refname; + struct reftable_stack *stack; +}; + +static int write_reflog_existence_table(struct reftable_writer *writer, + void *cb_data) +{ + struct write_reflog_existence_arg *arg = cb_data; + uint64_t ts = reftable_stack_next_update_index(arg->stack); + struct reftable_log_record log = {0}; + int ret; + + ret = reftable_stack_read_log(arg->stack, arg->refname, &log); + if (ret <= 0) + goto done; + + reftable_writer_set_limits(writer, ts, ts); + + /* + * The existence entry has both old and new object ID set to the the + * null object ID. Our iterators are aware of this and will not present + * them to their callers. + */ + log.refname = xstrdup(arg->refname); + log.update_index = ts; + log.value_type = REFTABLE_LOG_UPDATE; + ret = reftable_writer_add_log(writer, &log); + +done: + assert(ret != REFTABLE_API_ERROR); + reftable_log_record_release(&log); + return ret; +} + +static int reftable_be_create_reflog(struct ref_store *ref_store, + const char *refname, + struct strbuf *errmsg) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE, "create_reflog"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct write_reflog_existence_arg arg = { + .refs = refs, + .stack = stack, + .refname = refname, + }; + int ret; + + ret = refs->err; + if (ret < 0) + goto done; + + ret = reftable_stack_reload(stack); + if (ret) + goto done; + + ret = reftable_stack_add(stack, &write_reflog_existence_table, &arg); + +done: + return ret; +} + +struct write_reflog_delete_arg { + struct reftable_stack *stack; + const char *refname; +}; + +static int write_reflog_delete_table(struct reftable_writer *writer, void *cb_data) +{ + struct write_reflog_delete_arg *arg = cb_data; + struct reftable_merged_table *mt = + reftable_stack_merged_table(arg->stack); + struct reftable_log_record log = {0}, tombstone = {0}; + struct reftable_iterator it = {0}; + uint64_t ts = reftable_stack_next_update_index(arg->stack); + int ret; + + reftable_writer_set_limits(writer, ts, ts); + + /* + * In order to delete a table we need to delete all reflog entries one + * by one. This is inefficient, but the reftable format does not have a + * better marker right now. + */ + ret = reftable_merged_table_seek_log(mt, &it, arg->refname); + while (ret == 0) { + ret = reftable_iterator_next_log(&it, &log); + if (ret < 0) + break; + if (ret > 0 || strcmp(log.refname, arg->refname)) { + ret = 0; + break; + } + + tombstone.refname = (char *)arg->refname; + tombstone.value_type = REFTABLE_LOG_DELETION; + tombstone.update_index = log.update_index; + + ret = reftable_writer_add_log(writer, &tombstone); + } + + reftable_log_record_release(&log); + reftable_iterator_destroy(&it); + return ret; +} + +static int reftable_be_delete_reflog(struct ref_store *ref_store, + const char *refname) +{ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE, "delete_reflog"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct write_reflog_delete_arg arg = { + .stack = stack, + .refname = refname, + }; + int ret; + + ret = reftable_stack_reload(stack); + if (ret) + return ret; + ret = reftable_stack_add(stack, &write_reflog_delete_table, &arg); + + assert(ret != REFTABLE_API_ERROR); + return ret; +} + +struct reflog_expiry_arg { + struct reftable_stack *stack; + struct reftable_log_record *records; + struct object_id update_oid; + const char *refname; + size_t len; +}; + +static int write_reflog_expiry_table(struct reftable_writer *writer, void *cb_data) +{ + struct reflog_expiry_arg *arg = cb_data; + uint64_t ts = reftable_stack_next_update_index(arg->stack); + uint64_t live_records = 0; + size_t i; + int ret; + + for (i = 0; i < arg->len; i++) + if (arg->records[i].value_type == REFTABLE_LOG_UPDATE) + live_records++; + + reftable_writer_set_limits(writer, ts, ts); + + if (!is_null_oid(&arg->update_oid)) { + struct reftable_ref_record ref = {0}; + struct object_id peeled; + + ref.refname = (char *)arg->refname; + ref.update_index = ts; + + if (!peel_object(&arg->update_oid, &peeled)) { + ref.value_type = REFTABLE_REF_VAL2; + memcpy(ref.value.val2.target_value, peeled.hash, GIT_MAX_RAWSZ); + memcpy(ref.value.val2.value, arg->update_oid.hash, GIT_MAX_RAWSZ); + } else { + ref.value_type = REFTABLE_REF_VAL1; + memcpy(ref.value.val1, arg->update_oid.hash, GIT_MAX_RAWSZ); + } + + ret = reftable_writer_add_ref(writer, &ref); + if (ret < 0) + return ret; + } + + /* + * When there are no more entries left in the reflog we empty it + * completely, but write a placeholder reflog entry that indicates that + * the reflog still exists. + */ + if (!live_records) { + struct reftable_log_record log = { + .refname = (char *)arg->refname, + .value_type = REFTABLE_LOG_UPDATE, + .update_index = ts, + }; + + ret = reftable_writer_add_log(writer, &log); + if (ret) + return ret; + } + + for (i = 0; i < arg->len; i++) { + ret = reftable_writer_add_log(writer, &arg->records[i]); + if (ret) + return ret; + } + + return 0; +} + +static int reftable_be_reflog_expire(struct ref_store *ref_store, + const char *refname, + unsigned int flags, + reflog_expiry_prepare_fn prepare_fn, + reflog_expiry_should_prune_fn should_prune_fn, + reflog_expiry_cleanup_fn cleanup_fn, + void *policy_cb_data) +{ + /* + * For log expiry, we write tombstones for every single reflog entry + * that is to be expired. This means that the entries are still + * retrievable by delving into the stack, and expiring entries + * paradoxically takes extra memory. This memory is only reclaimed when + * compacting the reftable stack. + * + * It would be better if the refs backend supported an API that sets a + * criterion for all refs, passing the criterion to pack_refs(). + * + * On the plus side, because we do the expiration per ref, we can easily + * insert the reflog existence dummies. + */ + struct reftable_ref_store *refs = + reftable_be_downcast(ref_store, REF_STORE_WRITE, "reflog_expire"); + struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_merged_table *mt = reftable_stack_merged_table(stack); + struct reftable_log_record *logs = NULL; + struct reftable_log_record *rewritten = NULL; + struct reftable_ref_record ref_record = {0}; + struct reftable_iterator it = {0}; + struct reftable_addition *add = NULL; + struct reflog_expiry_arg arg = {0}; + struct object_id oid = {0}; + uint8_t *last_hash = NULL; + size_t logs_nr = 0, logs_alloc = 0, i; + int ret; + + if (refs->err < 0) + return refs->err; + + ret = reftable_stack_reload(stack); + if (ret < 0) + goto done; + + ret = reftable_merged_table_seek_log(mt, &it, refname); + if (ret < 0) + goto done; + + ret = reftable_stack_new_addition(&add, stack); + if (ret < 0) + goto done; + + ret = reftable_stack_read_ref(stack, refname, &ref_record); + if (ret < 0) + goto done; + if (reftable_ref_record_val1(&ref_record)) + oidread(&oid, reftable_ref_record_val1(&ref_record)); + prepare_fn(refname, &oid, policy_cb_data); + + while (1) { + struct reftable_log_record log = {0}; + struct object_id old_oid, new_oid; + + ret = reftable_iterator_next_log(&it, &log); + if (ret < 0) + goto done; + if (ret > 0 || strcmp(log.refname, refname)) { + reftable_log_record_release(&log); + break; + } + + oidread(&old_oid, log.value.update.old_hash); + oidread(&new_oid, log.value.update.new_hash); + + /* + * Skip over the reflog existence marker. We will add it back + * in when there are no live reflog records. + */ + if (is_null_oid(&old_oid) && is_null_oid(&new_oid)) { + reftable_log_record_release(&log); + continue; + } + + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); + logs[logs_nr++] = log; + } + + /* + * We need to rewrite all reflog entries according to the pruning + * callback function: + * + * - If a reflog entry shall be pruned we mark the record for + * deletion. + * + * - Otherwise we may have to rewrite the chain of reflog entries so + * that gaps created by just-deleted records get backfilled. + */ + CALLOC_ARRAY(rewritten, logs_nr); + for (i = logs_nr; i--;) { + struct reftable_log_record *dest = &rewritten[i]; + struct object_id old_oid, new_oid; + + *dest = logs[i]; + oidread(&old_oid, logs[i].value.update.old_hash); + oidread(&new_oid, logs[i].value.update.new_hash); + + if (should_prune_fn(&old_oid, &new_oid, logs[i].value.update.email, + (timestamp_t)logs[i].value.update.time, + logs[i].value.update.tz_offset, + logs[i].value.update.message, + policy_cb_data)) { + dest->value_type = REFTABLE_LOG_DELETION; + } else { + if ((flags & EXPIRE_REFLOGS_REWRITE) && last_hash) + dest->value.update.old_hash = last_hash; + last_hash = logs[i].value.update.new_hash; + } + } + + if (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash && + reftable_ref_record_val1(&ref_record)) + oidread(&arg.update_oid, last_hash); + + arg.records = rewritten; + arg.len = logs_nr; + arg.stack = stack, + arg.refname = refname, + + ret = reftable_addition_add(add, &write_reflog_expiry_table, &arg); + if (ret < 0) + goto done; + + /* + * Future improvement: we could skip writing records that were + * not changed. + */ + if (!(flags & EXPIRE_REFLOGS_DRY_RUN)) + ret = reftable_addition_commit(add); + +done: + if (add) + cleanup_fn(policy_cb_data); + assert(ret != REFTABLE_API_ERROR); + + reftable_ref_record_release(&ref_record); + reftable_iterator_destroy(&it); + reftable_addition_destroy(add); + for (i = 0; i < logs_nr; i++) + reftable_log_record_release(&logs[i]); + free(logs); + free(rewritten); + return ret; +} + +struct ref_storage_be refs_be_reftable = { + .name = "reftable", + .init = reftable_be_init, + .init_db = reftable_be_init_db, + .transaction_prepare = reftable_be_transaction_prepare, + .transaction_finish = reftable_be_transaction_finish, + .transaction_abort = reftable_be_transaction_abort, + .initial_transaction_commit = reftable_be_initial_transaction_commit, + + .pack_refs = reftable_be_pack_refs, + .create_symref = reftable_be_create_symref, + .rename_ref = reftable_be_rename_ref, + .copy_ref = reftable_be_copy_ref, + + .iterator_begin = reftable_be_iterator_begin, + .read_raw_ref = reftable_be_read_raw_ref, + .read_symbolic_ref = reftable_be_read_symbolic_ref, + + .reflog_iterator_begin = reftable_be_reflog_iterator_begin, + .for_each_reflog_ent = reftable_be_for_each_reflog_ent, + .for_each_reflog_ent_reverse = reftable_be_for_each_reflog_ent_reverse, + .reflog_exists = reftable_be_reflog_exists, + .create_reflog = reftable_be_create_reflog, + .delete_reflog = reftable_be_delete_reflog, + .reflog_expire = reftable_be_reflog_expire, +}; diff --git a/reftable/basics.c b/reftable/basics.c index f761e48028..0785aff941 100644 --- a/reftable/basics.c +++ b/reftable/basics.c @@ -64,12 +64,11 @@ void free_names(char **a) reftable_free(a); } -int names_length(char **names) +size_t names_length(char **names) { char **p = names; - for (; *p; p++) { - /* empty */ - } + while (*p) + p++; return p - names; } @@ -89,17 +88,13 @@ void parse_names(char *buf, int size, char ***namesp) next = end; } if (p < next) { - if (names_len == names_cap) { - names_cap = 2 * names_cap + 1; - names = reftable_realloc( - names, names_cap * sizeof(*names)); - } + REFTABLE_ALLOC_GROW(names, names_len + 1, names_cap); names[names_len++] = xstrdup(p); } p = next + 1; } - names = reftable_realloc(names, (names_len + 1) * sizeof(*names)); + REFTABLE_REALLOC_ARRAY(names, names_len + 1); names[names_len] = NULL; *namesp = names; } diff --git a/reftable/basics.h b/reftable/basics.h index 096b36862b..91f3533efe 100644 --- a/reftable/basics.h +++ b/reftable/basics.h @@ -44,14 +44,27 @@ void parse_names(char *buf, int size, char ***namesp); int names_equal(char **a, char **b); /* returns the array size of a NULL-terminated array of strings. */ -int names_length(char **names); +size_t names_length(char **names); /* Allocation routines; they invoke the functions set through * reftable_set_alloc() */ void *reftable_malloc(size_t sz); void *reftable_realloc(void *p, size_t sz); void reftable_free(void *p); -void *reftable_calloc(size_t sz); +void *reftable_calloc(size_t nelem, size_t elsize); + +#define REFTABLE_ALLOC_ARRAY(x, alloc) (x) = reftable_malloc(st_mult(sizeof(*(x)), (alloc))) +#define REFTABLE_CALLOC_ARRAY(x, alloc) (x) = reftable_calloc((alloc), sizeof(*(x))) +#define REFTABLE_REALLOC_ARRAY(x, alloc) (x) = reftable_realloc((x), st_mult(sizeof(*(x)), (alloc))) +#define REFTABLE_ALLOC_GROW(x, nr, alloc) \ + do { \ + if ((nr) > alloc) { \ + alloc = 2 * (alloc) + 1; \ + if (alloc < (nr)) \ + alloc = (nr); \ + REFTABLE_REALLOC_ARRAY(x, alloc); \ + } \ + } while (0) /* Find the longest shared prefix size of `a` and `b` */ struct strbuf; diff --git a/reftable/block.c b/reftable/block.c index 34d4d07369..72eb73b380 100644 --- a/reftable/block.c +++ b/reftable/block.c @@ -51,12 +51,7 @@ static int block_writer_register_restart(struct block_writer *w, int n, if (2 + 3 * rlen + n > w->block_size - w->next) return -1; if (is_restart) { - if (w->restart_len == w->restart_cap) { - w->restart_cap = w->restart_cap * 2 + 1; - w->restarts = reftable_realloc( - w->restarts, sizeof(uint32_t) * w->restart_cap); - } - + REFTABLE_ALLOC_GROW(w->restarts, w->restart_len + 1, w->restart_cap); w->restarts[w->restart_len++] = w->next; } @@ -148,8 +143,10 @@ int block_writer_finish(struct block_writer *w) int block_header_skip = 4 + w->header_off; uLongf src_len = w->next - block_header_skip; uLongf dest_cap = src_len * 1.001 + 12; + uint8_t *compressed; + + REFTABLE_ALLOC_ARRAY(compressed, dest_cap); - uint8_t *compressed = reftable_malloc(dest_cap); while (1) { uLongf out_dest_len = dest_cap; int zresult = compress2(compressed, &out_dest_len, @@ -206,9 +203,9 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block, uLongf dst_len = sz - block_header_skip; /* total size of dest buffer. */ uLongf src_len = block->len - block_header_skip; - /* Log blocks specify the *uncompressed* size in their header. - */ - uncompressed = reftable_malloc(sz); + + /* Log blocks specify the *uncompressed* size in their header. */ + REFTABLE_ALLOC_ARRAY(uncompressed, sz); /* Copy over the block header verbatim. It's not compressed. */ memcpy(uncompressed, block->data, block_header_skip); @@ -323,30 +320,27 @@ int block_iter_next(struct block_iter *it, struct reftable_record *rec) .len = it->br->block_len - it->next_off, }; struct string_view start = in; - struct strbuf key = STRBUF_INIT; uint8_t extra = 0; int n = 0; if (it->next_off >= it->br->block_len) return 1; - n = reftable_decode_key(&key, &extra, it->last_key, in); + n = reftable_decode_key(&it->key, &extra, it->last_key, in); if (n < 0) return -1; - if (!key.len) + if (!it->key.len) return REFTABLE_FORMAT_ERROR; string_view_consume(&in, n); - n = reftable_record_decode(rec, key, extra, in, it->br->hash_size); + n = reftable_record_decode(rec, it->key, extra, in, it->br->hash_size); if (n < 0) return -1; string_view_consume(&in, n); - strbuf_reset(&it->last_key); - strbuf_addbuf(&it->last_key, &key); + strbuf_swap(&it->last_key, &it->key); it->next_off += start.len - in.len; - strbuf_release(&key); return 0; } @@ -377,6 +371,7 @@ int block_iter_seek(struct block_iter *it, struct strbuf *want) void block_iter_close(struct block_iter *it) { strbuf_release(&it->last_key); + strbuf_release(&it->key); } int block_reader_seek(struct block_reader *br, struct block_iter *it, @@ -386,26 +381,23 @@ int block_reader_seek(struct block_reader *br, struct block_iter *it, .key = *want, .r = br, }; - struct reftable_record rec = reftable_new_record(block_reader_type(br)); - struct strbuf key = STRBUF_INIT; - int err = 0; - struct block_iter next = { - .last_key = STRBUF_INIT, - }; + struct block_iter next = BLOCK_ITER_INIT; + struct reftable_record rec; + int err = 0, i; - int i = binsearch(br->restart_count, &restart_key_less, &args); if (args.error) { err = REFTABLE_FORMAT_ERROR; goto done; } - it->br = br; - if (i > 0) { - i--; - it->next_off = block_reader_restart_offset(br, i); - } else { + i = binsearch(br->restart_count, &restart_key_less, &args); + if (i > 0) + it->next_off = block_reader_restart_offset(br, i - 1); + else it->next_off = br->header_off + 4; - } + it->br = br; + + reftable_record_init(&rec, block_reader_type(br)); /* We're looking for the last entry less/equal than the wanted key, so we have to go one entry too far and then back up. @@ -416,8 +408,8 @@ int block_reader_seek(struct block_reader *br, struct block_iter *it, if (err < 0) goto done; - reftable_record_key(&rec, &key); - if (err > 0 || strbuf_cmp(&key, want) >= 0) { + reftable_record_key(&rec, &it->key); + if (err > 0 || strbuf_cmp(&it->key, want) >= 0) { err = 0; goto done; } @@ -426,8 +418,7 @@ int block_reader_seek(struct block_reader *br, struct block_iter *it, } done: - strbuf_release(&key); - strbuf_release(&next.last_key); + block_iter_close(&next); reftable_record_release(&rec); return err; diff --git a/reftable/block.h b/reftable/block.h index 87c77539b5..17481e6331 100644 --- a/reftable/block.h +++ b/reftable/block.h @@ -84,8 +84,14 @@ struct block_iter { /* key for last entry we read. */ struct strbuf last_key; + struct strbuf key; }; +#define BLOCK_ITER_INIT { \ + .last_key = STRBUF_INIT, \ + .key = STRBUF_INIT, \ +} + /* initializes a block reader. */ int block_reader_init(struct block_reader *br, struct reftable_block *bl, uint32_t header_off, uint32_t table_block_size, diff --git a/reftable/block_test.c b/reftable/block_test.c index cb88af4a56..e162c6e33f 100644 --- a/reftable/block_test.c +++ b/reftable/block_test.c @@ -32,11 +32,11 @@ static void test_block_read_write(void) int i = 0; int n; struct block_reader br = { 0 }; - struct block_iter it = { .last_key = STRBUF_INIT }; + struct block_iter it = BLOCK_ITER_INIT; int j = 0; struct strbuf want = STRBUF_INIT; - block.data = reftable_calloc(block_size); + REFTABLE_CALLOC_ARRAY(block.data, block_size); block.len = block_size; block.source = malloc_block_source(); block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size, @@ -49,13 +49,11 @@ static void test_block_read_write(void) for (i = 0; i < N; i++) { char name[100]; - uint8_t hash[GIT_SHA1_RAWSZ]; snprintf(name, sizeof(name), "branch%02d", i); - memset(hash, i, sizeof(hash)); rec.u.ref.refname = name; rec.u.ref.value_type = REFTABLE_REF_VAL1; - rec.u.ref.value.val1 = hash; + memset(rec.u.ref.value.val1, i, GIT_SHA1_RAWSZ); names[i] = xstrdup(name); n = block_writer_add(&bw, &rec); @@ -87,7 +85,7 @@ static void test_block_read_write(void) block_iter_close(&it); for (i = 0; i < N; i++) { - struct block_iter it = { .last_key = STRBUF_INIT }; + struct block_iter it = BLOCK_ITER_INIT; strbuf_reset(&want); strbuf_addstr(&want, names[i]); diff --git a/reftable/blocksource.c b/reftable/blocksource.c index 8331b34e82..eeed254ba9 100644 --- a/reftable/blocksource.c +++ b/reftable/blocksource.c @@ -29,7 +29,7 @@ static int strbuf_read_block(void *v, struct reftable_block *dest, uint64_t off, { struct strbuf *b = v; assert(off + size <= b->len); - dest->data = reftable_calloc(size); + REFTABLE_CALLOC_ARRAY(dest->data, size); memcpy(dest->data, b->buf + off, size); dest->len = size; return size; @@ -76,8 +76,8 @@ struct reftable_block_source malloc_block_source(void) } struct file_block_source { - int fd; uint64_t size; + unsigned char *data; }; static uint64_t file_size(void *b) @@ -87,19 +87,12 @@ static uint64_t file_size(void *b) static void file_return_block(void *b, struct reftable_block *dest) { - if (dest->len) - memset(dest->data, 0xff, dest->len); - reftable_free(dest->data); } -static void file_close(void *b) +static void file_close(void *v) { - int fd = ((struct file_block_source *)b)->fd; - if (fd > 0) { - close(fd); - ((struct file_block_source *)b)->fd = 0; - } - + struct file_block_source *b = v; + munmap(b->data, b->size); reftable_free(b); } @@ -108,9 +101,7 @@ static int file_read_block(void *v, struct reftable_block *dest, uint64_t off, { struct file_block_source *b = v; assert(off + size <= b->size); - dest->data = reftable_malloc(size); - if (pread(b->fd, dest->data, size, off) != size) - return -1; + dest->data = b->data + off; dest->len = size; return size; } @@ -125,26 +116,26 @@ static struct reftable_block_source_vtable file_vtable = { int reftable_block_source_from_file(struct reftable_block_source *bs, const char *name) { - struct stat st = { 0 }; - int err = 0; - int fd = open(name, O_RDONLY); - struct file_block_source *p = NULL; + struct file_block_source *p; + struct stat st; + int fd; + + fd = open(name, O_RDONLY); if (fd < 0) { - if (errno == ENOENT) { + if (errno == ENOENT) return REFTABLE_NOT_EXIST_ERROR; - } return -1; } - err = fstat(fd, &st); - if (err < 0) { + if (fstat(fd, &st) < 0) { close(fd); return REFTABLE_IO_ERROR; } - p = reftable_calloc(sizeof(struct file_block_source)); + REFTABLE_CALLOC_ARRAY(p, 1); p->size = st.st_size; - p->fd = fd; + p->data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + close(fd); assert(!bs->ops); bs->ops = &file_vtable; diff --git a/reftable/dump.c b/reftable/dump.c index ce936b4e18..26e0393c7d 100644 --- a/reftable/dump.c +++ b/reftable/dump.c @@ -11,14 +11,12 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable-blocksource.h" #include "reftable-error.h" -#include "reftable-merged.h" #include "reftable-record.h" #include "reftable-tests.h" #include "reftable-writer.h" #include "reftable-iterator.h" #include "reftable-reader.h" #include "reftable-stack.h" -#include "reftable-generic.h" #include <stddef.h> #include <stdio.h> diff --git a/reftable/generic.c b/reftable/generic.c index 57f8032db9..b9f1c7c18a 100644 --- a/reftable/generic.c +++ b/reftable/generic.c @@ -6,7 +6,6 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ -#include "basics.h" #include "constants.h" #include "record.h" #include "generic.h" diff --git a/reftable/iter.c b/reftable/iter.c index a8d174c040..8b5ebf6183 100644 --- a/reftable/iter.c +++ b/reftable/iter.c @@ -160,8 +160,7 @@ int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest, int oid_len, uint64_t *offsets, int offset_len) { struct indexed_table_ref_iter empty = INDEXED_TABLE_REF_ITER_INIT; - struct indexed_table_ref_iter *itr = - reftable_calloc(sizeof(struct indexed_table_ref_iter)); + struct indexed_table_ref_iter *itr = reftable_calloc(1, sizeof(*itr)); int err = 0; *itr = empty; diff --git a/reftable/iter.h b/reftable/iter.h index 09eb0cbfa5..47d67d84df 100644 --- a/reftable/iter.h +++ b/reftable/iter.h @@ -53,10 +53,10 @@ struct indexed_table_ref_iter { int is_finished; }; -#define INDEXED_TABLE_REF_ITER_INIT \ - { \ - .cur = { .last_key = STRBUF_INIT }, .oid = STRBUF_INIT, \ - } +#define INDEXED_TABLE_REF_ITER_INIT { \ + .cur = BLOCK_ITER_INIT, \ + .oid = STRBUF_INIT, \ +} void iterator_from_indexed_table_ref_iter(struct reftable_iterator *it, struct indexed_table_ref_iter *itr); diff --git a/reftable/merged.c b/reftable/merged.c index 5ded470c08..1aa6cd31b7 100644 --- a/reftable/merged.c +++ b/reftable/merged.c @@ -11,7 +11,6 @@ https://developers.google.com/open-source/licenses/bsd #include "constants.h" #include "iter.h" #include "pq.h" -#include "reader.h" #include "record.h" #include "generic.h" #include "reftable-merged.h" @@ -20,24 +19,23 @@ https://developers.google.com/open-source/licenses/bsd static int merged_iter_init(struct merged_iter *mi) { - int i = 0; - for (i = 0; i < mi->stack_len; i++) { - struct reftable_record rec = reftable_new_record(mi->typ); - int err = iterator_next(&mi->stack[i], &rec); - if (err < 0) { + for (size_t i = 0; i < mi->stack_len; i++) { + struct pq_entry e = { + .index = i, + }; + int err; + + reftable_record_init(&e.rec, mi->typ); + err = iterator_next(&mi->stack[i], &e.rec); + if (err < 0) return err; - } - if (err > 0) { reftable_iterator_destroy(&mi->stack[i]); - reftable_record_release(&rec); - } else { - struct pq_entry e = { - .rec = rec, - .index = i, - }; - merged_iter_pqueue_add(&mi->pq, &e); + reftable_record_release(&e.rec); + continue; } + + merged_iter_pqueue_add(&mi->pq, &e); } return 0; @@ -46,11 +44,10 @@ static int merged_iter_init(struct merged_iter *mi) static void merged_iter_close(void *p) { struct merged_iter *mi = p; - int i = 0; + merged_iter_pqueue_release(&mi->pq); - for (i = 0; i < mi->stack_len; i++) { + for (size_t i = 0; i < mi->stack_len; i++) reftable_iterator_destroy(&mi->stack[i]); - } reftable_free(mi->stack); } @@ -58,10 +55,12 @@ static int merged_iter_advance_nonnull_subiter(struct merged_iter *mi, size_t idx) { struct pq_entry e = { - .rec = reftable_new_record(mi->typ), .index = idx, }; - int err = iterator_next(&mi->stack[idx], &e.rec); + int err; + + reftable_record_init(&e.rec, mi->typ); + err = iterator_next(&mi->stack[idx], &e.rec); if (err < 0) return err; @@ -85,7 +84,6 @@ static int merged_iter_advance_subiter(struct merged_iter *mi, size_t idx) static int merged_iter_next_entry(struct merged_iter *mi, struct reftable_record *rec) { - struct strbuf entry_key = STRBUF_INIT; struct pq_entry entry = { 0 }; int err = 0; @@ -105,33 +103,36 @@ static int merged_iter_next_entry(struct merged_iter *mi, such a deployment, the loop below must be changed to collect all entries for the same key, and return new the newest one. */ - reftable_record_key(&entry.rec, &entry_key); while (!merged_iter_pqueue_is_empty(mi->pq)) { struct pq_entry top = merged_iter_pqueue_top(mi->pq); - struct strbuf k = STRBUF_INIT; - int err = 0, cmp = 0; - - reftable_record_key(&top.rec, &k); - - cmp = strbuf_cmp(&k, &entry_key); - strbuf_release(&k); + int cmp; + + /* + * When the next entry comes from the same queue as the current + * entry then it must by definition be larger. This avoids a + * comparison in the most common case. + */ + if (top.index == entry.index) + break; - if (cmp > 0) { + cmp = reftable_record_cmp(&top.rec, &entry.rec); + if (cmp > 0) break; - } merged_iter_pqueue_remove(&mi->pq); err = merged_iter_advance_subiter(mi, top.index); - if (err < 0) { - return err; - } + if (err < 0) + goto done; reftable_record_release(&top.rec); } - reftable_record_copy_from(rec, &entry.rec, hash_size(mi->hash_id)); - reftable_record_release(&entry.rec); - strbuf_release(&entry_key); - return 0; + reftable_record_release(rec); + *rec = entry.rec; + +done: + if (err) + reftable_record_release(&entry.rec); + return err; } static int merged_iter_next(struct merged_iter *mi, struct reftable_record *rec) @@ -170,14 +171,14 @@ static void iterator_from_merged_iter(struct reftable_iterator *it, } int reftable_new_merged_table(struct reftable_merged_table **dest, - struct reftable_table *stack, int n, + struct reftable_table *stack, size_t n, uint32_t hash_id) { struct reftable_merged_table *m = NULL; uint64_t last_max = 0; uint64_t first_min = 0; - int i = 0; - for (i = 0; i < n; i++) { + + for (size_t i = 0; i < n; i++) { uint64_t min = reftable_table_min_update_index(&stack[i]); uint64_t max = reftable_table_max_update_index(&stack[i]); @@ -192,7 +193,7 @@ int reftable_new_merged_table(struct reftable_merged_table **dest, } } - m = reftable_calloc(sizeof(struct reftable_merged_table)); + REFTABLE_CALLOC_ARRAY(m, 1); m->stack = stack; m->stack_len = n; m->min = first_min; @@ -241,48 +242,36 @@ static int merged_table_seek_record(struct reftable_merged_table *mt, struct reftable_iterator *it, struct reftable_record *rec) { - struct reftable_iterator *iters = reftable_calloc( - sizeof(struct reftable_iterator) * mt->stack_len); struct merged_iter merged = { - .stack = iters, .typ = reftable_record_type(rec), .hash_id = mt->hash_id, .suppress_deletions = mt->suppress_deletions, }; - int n = 0; - int err = 0; - int i = 0; - for (i = 0; i < mt->stack_len && err == 0; i++) { - int e = reftable_table_seek_record(&mt->stack[i], &iters[n], - rec); - if (e < 0) { - err = e; - } - if (e == 0) { - n++; - } - } - if (err < 0) { - int i = 0; - for (i = 0; i < n; i++) { - reftable_iterator_destroy(&iters[i]); - } - reftable_free(iters); - return err; + struct merged_iter *p; + int err; + + REFTABLE_CALLOC_ARRAY(merged.stack, mt->stack_len); + for (size_t i = 0; i < mt->stack_len; i++) { + err = reftable_table_seek_record(&mt->stack[i], + &merged.stack[merged.stack_len], rec); + if (err < 0) + goto out; + if (!err) + merged.stack_len++; } - merged.stack_len = n; err = merged_iter_init(&merged); - if (err < 0) { + if (err < 0) + goto out; + + p = reftable_malloc(sizeof(struct merged_iter)); + *p = merged; + iterator_from_merged_iter(it, p); + +out: + if (err < 0) merged_iter_close(&merged); - return err; - } else { - struct merged_iter *p = - reftable_malloc(sizeof(struct merged_iter)); - *p = merged; - iterator_from_merged_iter(it, p); - } - return 0; + return err; } int reftable_merged_table_seek_ref(struct reftable_merged_table *mt, diff --git a/reftable/merged_test.c b/reftable/merged_test.c index d08c16abef..d0f77a3b8f 100644 --- a/reftable/merged_test.c +++ b/reftable/merged_test.c @@ -12,7 +12,6 @@ https://developers.google.com/open-source/licenses/bsd #include "basics.h" #include "blocksource.h" -#include "constants.h" #include "reader.h" #include "record.h" #include "test_framework.h" @@ -43,7 +42,7 @@ static void write_test_table(struct strbuf *buf, } } - w = reftable_new_writer(&strbuf_add_void, buf, &opts); + w = reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts); reftable_writer_set_limits(w, min, max); for (i = 0; i < n; i++) { @@ -71,7 +70,7 @@ static void write_test_log_table(struct strbuf *buf, .exact_log_message = 1, }; struct reftable_writer *w = NULL; - w = reftable_new_writer(&strbuf_add_void, buf, &opts); + w = reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts); reftable_writer_set_limits(w, update_index, update_index); for (i = 0; i < n; i++) { @@ -89,16 +88,17 @@ static struct reftable_merged_table * merged_table_from_records(struct reftable_ref_record **refs, struct reftable_block_source **source, struct reftable_reader ***readers, int *sizes, - struct strbuf *buf, int n) + struct strbuf *buf, size_t n) { - int i = 0; struct reftable_merged_table *mt = NULL; + struct reftable_table *tabs; int err; - struct reftable_table *tabs = - reftable_calloc(n * sizeof(struct reftable_table)); - *readers = reftable_calloc(n * sizeof(struct reftable_reader *)); - *source = reftable_calloc(n * sizeof(**source)); - for (i = 0; i < n; i++) { + + REFTABLE_CALLOC_ARRAY(tabs, n); + REFTABLE_CALLOC_ARRAY(*readers, n); + REFTABLE_CALLOC_ARRAY(*source, n); + + for (size_t i = 0; i < n; i++) { write_test_table(&buf[i], refs[i], sizes[i]); block_source_from_strbuf(&(*source)[i], &buf[i]); @@ -123,13 +123,11 @@ static void readers_destroy(struct reftable_reader **readers, size_t n) static void test_merged_between(void) { - uint8_t hash1[GIT_SHA1_RAWSZ] = { 1, 2, 3, 0 }; - struct reftable_ref_record r1[] = { { .refname = "b", .update_index = 1, .value_type = REFTABLE_REF_VAL1, - .value.val1 = hash1, + .value.val1 = { 1, 2, 3, 0 }, } }; struct reftable_ref_record r2[] = { { .refname = "a", @@ -165,26 +163,24 @@ static void test_merged_between(void) static void test_merged(void) { - uint8_t hash1[GIT_SHA1_RAWSZ] = { 1 }; - uint8_t hash2[GIT_SHA1_RAWSZ] = { 2 }; struct reftable_ref_record r1[] = { { .refname = "a", .update_index = 1, .value_type = REFTABLE_REF_VAL1, - .value.val1 = hash1, + .value.val1 = { 1 }, }, { .refname = "b", .update_index = 1, .value_type = REFTABLE_REF_VAL1, - .value.val1 = hash1, + .value.val1 = { 1 }, }, { .refname = "c", .update_index = 1, .value_type = REFTABLE_REF_VAL1, - .value.val1 = hash1, + .value.val1 = { 1 }, } }; struct reftable_ref_record r2[] = { { @@ -197,13 +193,13 @@ static void test_merged(void) .refname = "c", .update_index = 3, .value_type = REFTABLE_REF_VAL1, - .value.val1 = hash2, + .value.val1 = { 2 }, }, { .refname = "d", .update_index = 3, .value_type = REFTABLE_REF_VAL1, - .value.val1 = hash1, + .value.val1 = { 1 }, }, }; @@ -236,14 +232,10 @@ static void test_merged(void) while (len < 100) { /* cap loops/recursion. */ struct reftable_ref_record ref = { NULL }; int err = reftable_iterator_next_ref(&it, &ref); - if (err > 0) { + if (err > 0) break; - } - if (len == cap) { - cap = 2 * cap + 1; - out = reftable_realloc( - out, sizeof(struct reftable_ref_record) * cap); - } + + REFTABLE_ALLOC_GROW(out, len + 1, cap); out[len++] = ref; } reftable_iterator_destroy(&it); @@ -270,16 +262,17 @@ static struct reftable_merged_table * merged_table_from_log_records(struct reftable_log_record **logs, struct reftable_block_source **source, struct reftable_reader ***readers, int *sizes, - struct strbuf *buf, int n) + struct strbuf *buf, size_t n) { - int i = 0; struct reftable_merged_table *mt = NULL; + struct reftable_table *tabs; int err; - struct reftable_table *tabs = - reftable_calloc(n * sizeof(struct reftable_table)); - *readers = reftable_calloc(n * sizeof(struct reftable_reader *)); - *source = reftable_calloc(n * sizeof(**source)); - for (i = 0; i < n; i++) { + + REFTABLE_CALLOC_ARRAY(tabs, n); + REFTABLE_CALLOC_ARRAY(*readers, n); + REFTABLE_CALLOC_ARRAY(*source, n); + + for (size_t i = 0; i < n; i++) { write_test_log_table(&buf[i], logs[i], sizes[i], i + 1); block_source_from_strbuf(&(*source)[i], &buf[i]); @@ -373,14 +366,10 @@ static void test_merged_logs(void) while (len < 100) { /* cap loops/recursion. */ struct reftable_log_record log = { NULL }; int err = reftable_iterator_next_log(&it, &log); - if (err > 0) { + if (err > 0) break; - } - if (len == cap) { - cap = 2 * cap + 1; - out = reftable_realloc( - out, sizeof(struct reftable_log_record) * cap); - } + + REFTABLE_ALLOC_GROW(out, len + 1, cap); out[len++] = log; } reftable_iterator_destroy(&it); @@ -417,7 +406,7 @@ static void test_default_write_opts(void) struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); struct reftable_ref_record rec = { .refname = "master", @@ -425,7 +414,7 @@ static void test_default_write_opts(void) }; int err; struct reftable_block_source source = { NULL }; - struct reftable_table *tab = reftable_calloc(sizeof(*tab) * 1); + struct reftable_table *tab = reftable_calloc(1, sizeof(*tab)); uint32_t hash_id; struct reftable_reader *rd = NULL; struct reftable_merged_table *merged = NULL; diff --git a/reftable/pq.c b/reftable/pq.c index dcefeb793a..e0ccce2b97 100644 --- a/reftable/pq.c +++ b/reftable/pq.c @@ -14,20 +14,9 @@ https://developers.google.com/open-source/licenses/bsd int pq_less(struct pq_entry *a, struct pq_entry *b) { - struct strbuf ak = STRBUF_INIT; - struct strbuf bk = STRBUF_INIT; - int cmp = 0; - reftable_record_key(&a->rec, &ak); - reftable_record_key(&b->rec, &bk); - - cmp = strbuf_cmp(&ak, &bk); - - strbuf_release(&ak); - strbuf_release(&bk); - + int cmp = reftable_record_cmp(&a->rec, &b->rec); if (cmp == 0) return a->index > b->index; - return cmp < 0; } @@ -75,13 +64,9 @@ void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry { int i = 0; - if (pq->len == pq->cap) { - pq->cap = 2 * pq->cap + 1; - pq->heap = reftable_realloc(pq->heap, - pq->cap * sizeof(struct pq_entry)); - } - + REFTABLE_ALLOC_GROW(pq->heap, pq->len + 1, pq->cap); pq->heap[pq->len++] = *e; + i = pq->len - 1; while (i > 0) { int j = (i - 1) / 2; diff --git a/reftable/pq_test.c b/reftable/pq_test.c index 011b5c7502..c202eff848 100644 --- a/reftable/pq_test.c +++ b/reftable/pq_test.c @@ -60,7 +60,7 @@ static void test_pq(void) if (last) { EXPECT(strcmp(last, rec->u.ref.refname) < 0); } - // this is names[i], so don't dealloc. + /* this is names[i], so don't dealloc. */ last = rec->u.ref.refname; rec->u.ref.refname = NULL; reftable_record_release(rec); diff --git a/reftable/publicbasics.c b/reftable/publicbasics.c index bcb82530d6..44b84a125e 100644 --- a/reftable/publicbasics.c +++ b/reftable/publicbasics.c @@ -37,8 +37,9 @@ void reftable_free(void *p) free(p); } -void *reftable_calloc(size_t sz) +void *reftable_calloc(size_t nelem, size_t elsize) { + size_t sz = st_mult(nelem, elsize); void *p = reftable_malloc(sz); memset(p, 0, sz); return p; diff --git a/reftable/reader.c b/reftable/reader.c index b4db23ce18..b113daab77 100644 --- a/reftable/reader.c +++ b/reftable/reader.c @@ -16,7 +16,6 @@ https://developers.google.com/open-source/licenses/bsd #include "record.h" #include "reftable-error.h" #include "reftable-generic.h" -#include "tree.h" uint64_t block_source_size(struct reftable_block_source *source) { @@ -224,10 +223,9 @@ struct table_iter { struct block_iter bi; int is_finished; }; -#define TABLE_ITER_INIT \ - { \ - .bi = {.last_key = STRBUF_INIT } \ - } +#define TABLE_ITER_INIT { \ + .bi = BLOCK_ITER_INIT \ +} static void table_iter_copy_from(struct table_iter *dest, struct table_iter *src) @@ -359,24 +357,32 @@ static int table_iter_next(struct table_iter *ti, struct reftable_record *rec) while (1) { struct table_iter next = TABLE_ITER_INIT; - int err = 0; - if (ti->is_finished) { + int err; + + if (ti->is_finished) return 1; - } + /* + * Check whether the current block still has more records. If + * so, return it. If the iterator returns positive then the + * current block has been exhausted. + */ err = table_iter_next_in_block(ti, rec); - if (err <= 0) { + if (err <= 0) return err; - } + /* + * Otherwise, we need to continue to the next block in the + * table and retry. If there are no more blocks then the + * iterator is drained. + */ err = table_iter_next_block(&next, ti); - if (err != 0) { - ti->is_finished = 1; - } table_iter_block_done(ti); - if (err != 0) { + if (err) { + ti->is_finished = 1; return err; } + table_iter_copy_from(ti, &next); block_iter_close(&next.bi); } @@ -446,13 +452,13 @@ static int reader_start(struct reftable_reader *r, struct table_iter *ti, static int reader_seek_linear(struct table_iter *ti, struct reftable_record *want) { - struct reftable_record rec = - reftable_new_record(reftable_record_type(want)); struct strbuf want_key = STRBUF_INIT; struct strbuf got_key = STRBUF_INIT; struct table_iter next = TABLE_ITER_INIT; + struct reftable_record rec; int err = -1; + reftable_record_init(&rec, reftable_record_type(want)); reftable_record_key(want, &want_key); while (1) { @@ -510,8 +516,38 @@ static int reader_seek_indexed(struct reftable_reader *r, if (err < 0) goto done; + /* + * The index may consist of multiple levels, where each level may have + * multiple index blocks. We start by doing a linear search in the + * highest layer that identifies the relevant index block as well as + * the record inside that block that corresponds to our wanted key. + */ err = reader_seek_linear(&index_iter, &want_index); + if (err < 0) + goto done; + + /* + * Traverse down the levels until we find a non-index entry. + */ while (1) { + /* + * In case we seek a record that does not exist the index iter + * will tell us that the iterator is over. This works because + * the last index entry of the current level will contain the + * last key it knows about. So in case our seeked key is larger + * than the last indexed key we know that it won't exist. + * + * There is one subtlety in the layout of the index section + * that makes this work as expected: the highest-level index is + * at end of the section and will point backwards and thus we + * start reading from the end of the index section, not the + * beginning. + * + * If that wasn't the case and the order was reversed then the + * linear seek would seek into the lower levels and traverse + * all levels of the index only to find out that the key does + * not exist. + */ err = table_iter_next(&index_iter, &index_result); table_iter_block_done(&index_iter); if (err != 0) @@ -541,8 +577,7 @@ static int reader_seek_indexed(struct reftable_reader *r, if (err == 0) { struct table_iter empty = TABLE_ITER_INIT; - struct table_iter *malloced = - reftable_calloc(sizeof(struct table_iter)); + struct table_iter *malloced = reftable_calloc(1, sizeof(*malloced)); *malloced = empty; table_iter_copy_from(malloced, &next); iterator_from_table_iter(it, malloced); @@ -637,8 +672,7 @@ void reader_close(struct reftable_reader *r) int reftable_new_reader(struct reftable_reader **p, struct reftable_block_source *src, char const *name) { - struct reftable_reader *rd = - reftable_calloc(sizeof(struct reftable_reader)); + struct reftable_reader *rd = reftable_calloc(1, sizeof(*rd)); int err = init_reader(rd, src, name); if (err == 0) { *p = rd; @@ -713,7 +747,7 @@ static int reftable_reader_refs_for_unindexed(struct reftable_reader *r, uint8_t *oid) { struct table_iter ti_empty = TABLE_ITER_INIT; - struct table_iter *ti = reftable_calloc(sizeof(struct table_iter)); + struct table_iter *ti = reftable_calloc(1, sizeof(*ti)); struct filtering_ref_iterator *filter = NULL; struct filtering_ref_iterator empty = FILTERING_REF_ITERATOR_INIT; int oid_len = hash_size(r->hash_id); diff --git a/reftable/readwrite_test.c b/reftable/readwrite_test.c index 469ab79a5a..363fe0f998 100644 --- a/reftable/readwrite_test.c +++ b/reftable/readwrite_test.c @@ -11,7 +11,6 @@ https://developers.google.com/open-source/licenses/bsd #include "basics.h" #include "block.h" #include "blocksource.h" -#include "constants.h" #include "reader.h" #include "record.h" #include "test_framework.h" @@ -52,26 +51,25 @@ static void write_table(char ***names, struct strbuf *buf, int N, .hash_id = hash_id, }; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, buf, &opts); struct reftable_ref_record ref = { NULL }; int i = 0, n; struct reftable_log_record log = { NULL }; const struct reftable_stats *stats = NULL; - *names = reftable_calloc(sizeof(char *) * (N + 1)); + + REFTABLE_CALLOC_ARRAY(*names, N + 1); + reftable_writer_set_limits(w, update_index, update_index); for (i = 0; i < N; i++) { - uint8_t hash[GIT_SHA256_RAWSZ] = { 0 }; char name[100]; int n; - set_test_hash(hash, i); - snprintf(name, sizeof(name), "refs/heads/branch%02d", i); ref.refname = name; ref.update_index = update_index; ref.value_type = REFTABLE_REF_VAL1; - ref.value.val1 = hash; + set_test_hash(ref.value.val1, i); (*names)[i] = xstrdup(name); n = reftable_writer_add_ref(w, &ref); @@ -134,15 +132,15 @@ static void test_log_buffer_size(void) .message = "commit: 9\n", } } }; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); /* This tests buffer extension for log compression. Must use a random hash, to ensure that the compressed part is larger than the original. */ uint8_t hash1[GIT_SHA1_RAWSZ], hash2[GIT_SHA1_RAWSZ]; for (i = 0; i < GIT_SHA1_RAWSZ; i++) { - hash1[i] = (uint8_t)(rand() % 256); - hash2[i] = (uint8_t)(rand() % 256); + hash1[i] = (uint8_t)(git_rand() % 256); + hash2[i] = (uint8_t)(git_rand() % 256); } log.value.update.old_hash = hash1; log.value.update.new_hash = hash2; @@ -175,7 +173,7 @@ static void test_log_overflow(void) .message = msg, } } }; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); uint8_t hash1[GIT_SHA1_RAWSZ] = {1}, hash2[GIT_SHA1_RAWSZ] = { 2 }; @@ -192,7 +190,7 @@ static void test_log_overflow(void) static void test_log_write_read(void) { int N = 2; - char **names = reftable_calloc(sizeof(char *) * (N + 1)); + char **names = reftable_calloc(N + 1, sizeof(*names)); int err; struct reftable_write_options opts = { .block_size = 256, @@ -206,7 +204,7 @@ static void test_log_write_read(void) struct reftable_block_source source = { NULL }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); const struct reftable_stats *stats = NULL; reftable_writer_set_limits(w, 0, N); for (i = 0; i < N; i++) { @@ -298,7 +296,7 @@ static void test_log_zlib_corruption(void) struct reftable_block_source source = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); const struct reftable_stats *stats = NULL; uint8_t hash1[GIT_SHA1_RAWSZ] = { 1 }; uint8_t hash2[GIT_SHA1_RAWSZ] = { 2 }; @@ -320,7 +318,7 @@ static void test_log_zlib_corruption(void) }; for (i = 0; i < sizeof(message) - 1; i++) - message[i] = (uint8_t)(rand() % 64 + ' '); + message[i] = (uint8_t)(git_rand() % 64 + ' '); reftable_writer_set_limits(w, 1, 1); @@ -523,7 +521,7 @@ static void test_table_read_write_seek_index(void) static void test_table_refs_for(int indexed) { int N = 50; - char **want_names = reftable_calloc(sizeof(char *) * (N + 1)); + char **want_names = reftable_calloc(N + 1, sizeof(*want_names)); int want_names_len = 0; uint8_t want_hash[GIT_SHA1_RAWSZ]; @@ -539,7 +537,7 @@ static void test_table_refs_for(int indexed) struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); struct reftable_iterator it = { NULL }; int j; @@ -550,8 +548,6 @@ static void test_table_refs_for(int indexed) uint8_t hash[GIT_SHA1_RAWSZ]; char fill[51] = { 0 }; char name[100]; - uint8_t hash1[GIT_SHA1_RAWSZ]; - uint8_t hash2[GIT_SHA1_RAWSZ]; struct reftable_ref_record ref = { NULL }; memset(hash, i, sizeof(hash)); @@ -561,11 +557,9 @@ static void test_table_refs_for(int indexed) name[40] = 0; ref.refname = name; - set_test_hash(hash1, i / 4); - set_test_hash(hash2, 3 + i / 4); ref.value_type = REFTABLE_REF_VAL2; - ref.value.val2.value = hash1; - ref.value.val2.target_value = hash2; + set_test_hash(ref.value.val2.value, i / 4); + set_test_hash(ref.value.val2.target_value, 3 + i / 4); /* 80 bytes / entry, so 3 entries per block. Yields 17 */ @@ -573,8 +567,8 @@ static void test_table_refs_for(int indexed) n = reftable_writer_add_ref(w, &ref); EXPECT(n == 0); - if (!memcmp(hash1, want_hash, GIT_SHA1_RAWSZ) || - !memcmp(hash2, want_hash, GIT_SHA1_RAWSZ)) { + if (!memcmp(ref.value.val2.value, want_hash, GIT_SHA1_RAWSZ) || + !memcmp(ref.value.val2.target_value, want_hash, GIT_SHA1_RAWSZ)) { want_names[want_names_len++] = xstrdup(name); } } @@ -636,7 +630,7 @@ static void test_write_empty_table(void) struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); struct reftable_block_source source = { NULL }; struct reftable_reader *rd = NULL; struct reftable_ref_record rec = { NULL }; @@ -674,12 +668,11 @@ static void test_write_object_id_min_length(void) }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); - uint8_t hash[GIT_SHA1_RAWSZ] = {42}; + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); struct reftable_ref_record ref = { .update_index = 1, .value_type = REFTABLE_REF_VAL1, - .value.val1 = hash, + .value.val1 = {42}, }; int err; int i; @@ -710,12 +703,11 @@ static void test_write_object_id_length(void) }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); - uint8_t hash[GIT_SHA1_RAWSZ] = {42}; + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); struct reftable_ref_record ref = { .update_index = 1, .value_type = REFTABLE_REF_VAL1, - .value.val1 = hash, + .value.val1 = {42}, }; int err; int i; @@ -745,7 +737,7 @@ static void test_write_empty_key(void) struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); struct reftable_ref_record ref = { .refname = "", .update_index = 1, @@ -768,7 +760,7 @@ static void test_write_key_order(void) struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); struct reftable_ref_record refs[2] = { { .refname = "b", @@ -798,6 +790,139 @@ static void test_write_key_order(void) strbuf_release(&buf); } +static void test_write_multiple_indices(void) +{ + struct reftable_write_options opts = { + .block_size = 100, + }; + struct strbuf writer_buf = STRBUF_INIT, buf = STRBUF_INIT; + struct reftable_block_source source = { 0 }; + struct reftable_iterator it = { 0 }; + const struct reftable_stats *stats; + struct reftable_writer *writer; + struct reftable_reader *reader; + int err, i; + + writer = reftable_new_writer(&strbuf_add_void, &noop_flush, &writer_buf, &opts); + reftable_writer_set_limits(writer, 1, 1); + for (i = 0; i < 100; i++) { + struct reftable_ref_record ref = { + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = {i}, + }; + + strbuf_reset(&buf); + strbuf_addf(&buf, "refs/heads/%04d", i); + ref.refname = buf.buf, + + err = reftable_writer_add_ref(writer, &ref); + EXPECT_ERR(err); + } + + for (i = 0; i < 100; i++) { + unsigned char hash[GIT_SHA1_RAWSZ] = {i}; + struct reftable_log_record log = { + .update_index = 1, + .value_type = REFTABLE_LOG_UPDATE, + .value.update = { + .old_hash = hash, + .new_hash = hash, + }, + }; + + strbuf_reset(&buf); + strbuf_addf(&buf, "refs/heads/%04d", i); + log.refname = buf.buf, + + err = reftable_writer_add_log(writer, &log); + EXPECT_ERR(err); + } + + reftable_writer_close(writer); + + /* + * The written data should be sufficiently large to result in indices + * for each of the block types. + */ + stats = reftable_writer_stats(writer); + EXPECT(stats->ref_stats.index_offset > 0); + EXPECT(stats->obj_stats.index_offset > 0); + EXPECT(stats->log_stats.index_offset > 0); + + block_source_from_strbuf(&source, &writer_buf); + err = reftable_new_reader(&reader, &source, "filename"); + EXPECT_ERR(err); + + /* + * Seeking the log uses the log index now. In case there is any + * confusion regarding indices we would notice here. + */ + err = reftable_reader_seek_log(reader, &it, ""); + EXPECT_ERR(err); + + reftable_iterator_destroy(&it); + reftable_writer_free(writer); + reftable_reader_free(reader); + strbuf_release(&writer_buf); + strbuf_release(&buf); +} + +static void test_write_multi_level_index(void) +{ + struct reftable_write_options opts = { + .block_size = 100, + }; + struct strbuf writer_buf = STRBUF_INIT, buf = STRBUF_INIT; + struct reftable_block_source source = { 0 }; + struct reftable_iterator it = { 0 }; + const struct reftable_stats *stats; + struct reftable_writer *writer; + struct reftable_reader *reader; + int err; + + writer = reftable_new_writer(&strbuf_add_void, &noop_flush, &writer_buf, &opts); + reftable_writer_set_limits(writer, 1, 1); + for (size_t i = 0; i < 200; i++) { + struct reftable_ref_record ref = { + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = {i}, + }; + + strbuf_reset(&buf); + strbuf_addf(&buf, "refs/heads/%03" PRIuMAX, (uintmax_t)i); + ref.refname = buf.buf, + + err = reftable_writer_add_ref(writer, &ref); + EXPECT_ERR(err); + } + reftable_writer_close(writer); + + /* + * The written refs should be sufficiently large to result in a + * multi-level index. + */ + stats = reftable_writer_stats(writer); + EXPECT(stats->ref_stats.max_index_level == 2); + + block_source_from_strbuf(&source, &writer_buf); + err = reftable_new_reader(&reader, &source, "filename"); + EXPECT_ERR(err); + + /* + * Seeking the last ref should work as expected. + */ + err = reftable_reader_seek_ref(reader, &it, "refs/heads/199"); + EXPECT_ERR(err); + + reftable_iterator_destroy(&it); + reftable_writer_free(writer); + reftable_reader_free(reader); + strbuf_release(&writer_buf); + strbuf_release(&buf); +} + static void test_corrupt_table_empty(void) { struct strbuf buf = STRBUF_INIT; @@ -847,5 +972,7 @@ int readwrite_test_main(int argc, const char *argv[]) RUN_TEST(test_log_overflow); RUN_TEST(test_write_object_id_length); RUN_TEST(test_write_object_id_min_length); + RUN_TEST(test_write_multiple_indices); + RUN_TEST(test_write_multi_level_index); return 0; } diff --git a/reftable/record.c b/reftable/record.c index fbaa1fbef5..d6bb42e887 100644 --- a/reftable/record.c +++ b/reftable/record.c @@ -76,7 +76,7 @@ int reftable_is_block_type(uint8_t typ) return 0; } -uint8_t *reftable_ref_record_val1(const struct reftable_ref_record *rec) +const unsigned char *reftable_ref_record_val1(const struct reftable_ref_record *rec) { switch (rec->value_type) { case REFTABLE_REF_VAL1: @@ -88,7 +88,7 @@ uint8_t *reftable_ref_record_val1(const struct reftable_ref_record *rec) } } -uint8_t *reftable_ref_record_val2(const struct reftable_ref_record *rec) +const unsigned char *reftable_ref_record_val2(const struct reftable_ref_record *rec) { switch (rec->value_type) { case REFTABLE_REF_VAL2: @@ -219,13 +219,10 @@ static void reftable_ref_record_copy_from(void *rec, const void *src_rec, case REFTABLE_REF_DELETION: break; case REFTABLE_REF_VAL1: - ref->value.val1 = reftable_malloc(hash_size); memcpy(ref->value.val1, src->value.val1, hash_size); break; case REFTABLE_REF_VAL2: - ref->value.val2.value = reftable_malloc(hash_size); memcpy(ref->value.val2.value, src->value.val2.value, hash_size); - ref->value.val2.target_value = reftable_malloc(hash_size); memcpy(ref->value.val2.target_value, src->value.val2.target_value, hash_size); break; @@ -242,7 +239,7 @@ static char hexdigit(int c) return 'a' + (c - 10); } -static void hex_format(char *dest, uint8_t *src, int hash_size) +static void hex_format(char *dest, const unsigned char *src, int hash_size) { assert(hash_size > 0); if (src) { @@ -299,11 +296,8 @@ void reftable_ref_record_release(struct reftable_ref_record *ref) reftable_free(ref->value.symref); break; case REFTABLE_REF_VAL2: - reftable_free(ref->value.val2.target_value); - reftable_free(ref->value.val2.value); break; case REFTABLE_REF_VAL1: - reftable_free(ref->value.val1); break; case REFTABLE_REF_DELETION: break; @@ -383,10 +377,11 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, assert(hash_size > 0); - r->refname = reftable_realloc(r->refname, key.len + 1); + r->refname = reftable_malloc(key.len + 1); memcpy(r->refname, key.buf, key.len); - r->update_index = update_index; r->refname[key.len] = 0; + + r->update_index = update_index; r->value_type = val_type; switch (val_type) { case REFTABLE_REF_VAL1: @@ -394,7 +389,6 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, return -1; } - r->value.val1 = reftable_malloc(hash_size); memcpy(r->value.val1, in.buf, hash_size); string_view_consume(&in, hash_size); break; @@ -404,11 +398,9 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, return -1; } - r->value.val2.value = reftable_malloc(hash_size); memcpy(r->value.val2.value, in.buf, hash_size); string_view_consume(&in, hash_size); - r->value.val2.target_value = reftable_malloc(hash_size); memcpy(r->value.val2.target_value, in.buf, hash_size); string_view_consume(&in, hash_size); break; @@ -439,7 +431,6 @@ static int reftable_ref_record_is_deletion_void(const void *p) (const struct reftable_ref_record *)p); } - static int reftable_ref_record_equal_void(const void *a, const void *b, int hash_size) { @@ -448,6 +439,13 @@ static int reftable_ref_record_equal_void(const void *a, return reftable_ref_record_equal(ra, rb, hash_size); } +static int reftable_ref_record_cmp_void(const void *_a, const void *_b) +{ + const struct reftable_ref_record *a = _a; + const struct reftable_ref_record *b = _b; + return strcmp(a->refname, b->refname); +} + static void reftable_ref_record_print_void(const void *rec, int hash_size) { @@ -464,6 +462,7 @@ static struct reftable_record_vtable reftable_ref_record_vtable = { .release = &reftable_ref_record_release_void, .is_deletion = &reftable_ref_record_is_deletion_void, .equal = &reftable_ref_record_equal_void, + .cmp = &reftable_ref_record_cmp_void, .print = &reftable_ref_record_print_void, }; @@ -506,12 +505,13 @@ static void reftable_obj_record_copy_from(void *rec, const void *src_rec, (const struct reftable_obj_record *)src_rec; reftable_obj_record_release(obj); - obj->hash_prefix = reftable_malloc(src->hash_prefix_len); + + REFTABLE_ALLOC_ARRAY(obj->hash_prefix, src->hash_prefix_len); obj->hash_prefix_len = src->hash_prefix_len; if (src->hash_prefix_len) memcpy(obj->hash_prefix, src->hash_prefix, obj->hash_prefix_len); - obj->offsets = reftable_malloc(src->offset_len * sizeof(uint64_t)); + REFTABLE_ALLOC_ARRAY(obj->offsets, src->offset_len); obj->offset_len = src->offset_len; COPY_ARRAY(obj->offsets, src->offsets, src->offset_len); } @@ -568,7 +568,8 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key, int n = 0; uint64_t last; int j; - r->hash_prefix = reftable_malloc(key.len); + + REFTABLE_ALLOC_ARRAY(r->hash_prefix, key.len); memcpy(r->hash_prefix, key.buf, key.len); r->hash_prefix_len = key.len; @@ -586,7 +587,7 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key, if (count == 0) return start.len - in.len; - r->offsets = reftable_malloc(count * sizeof(uint64_t)); + REFTABLE_ALLOC_ARRAY(r->offsets, count); r->offset_len = count; n = get_var_int(&r->offsets[0], &in); @@ -634,6 +635,25 @@ static int reftable_obj_record_equal_void(const void *a, const void *b, int hash return 1; } +static int reftable_obj_record_cmp_void(const void *_a, const void *_b) +{ + const struct reftable_obj_record *a = _a; + const struct reftable_obj_record *b = _b; + int cmp; + + cmp = memcmp(a->hash_prefix, b->hash_prefix, + a->hash_prefix_len > b->hash_prefix_len ? + a->hash_prefix_len : b->hash_prefix_len); + if (cmp) + return cmp; + + /* + * When the prefix is the same then the object record that is longer is + * considered to be bigger. + */ + return a->hash_prefix_len - b->hash_prefix_len; +} + static struct reftable_record_vtable reftable_obj_record_vtable = { .key = &reftable_obj_record_key, .type = BLOCK_TYPE_OBJ, @@ -644,6 +664,7 @@ static struct reftable_record_vtable reftable_obj_record_vtable = { .release = &reftable_obj_record_release, .is_deletion = ¬_a_deletion, .equal = &reftable_obj_record_equal_void, + .cmp = &reftable_obj_record_cmp_void, .print = &reftable_obj_record_print, }; @@ -724,12 +745,12 @@ static void reftable_log_record_copy_from(void *rec, const void *src_rec, } if (dst->value.update.new_hash) { - dst->value.update.new_hash = reftable_malloc(hash_size); + REFTABLE_ALLOC_ARRAY(dst->value.update.new_hash, hash_size); memcpy(dst->value.update.new_hash, src->value.update.new_hash, hash_size); } if (dst->value.update.old_hash) { - dst->value.update.old_hash = reftable_malloc(hash_size); + REFTABLE_ALLOC_ARRAY(dst->value.update.old_hash, hash_size); memcpy(dst->value.update.old_hash, src->value.update.old_hash, hash_size); } @@ -962,6 +983,22 @@ static int reftable_log_record_equal_void(const void *a, hash_size); } +static int reftable_log_record_cmp_void(const void *_a, const void *_b) +{ + const struct reftable_log_record *a = _a; + const struct reftable_log_record *b = _b; + int cmp = strcmp(a->refname, b->refname); + if (cmp) + return cmp; + + /* + * Note that the comparison here is reversed. This is because the + * update index is reversed when comparing keys. For reference, see how + * we handle this in reftable_log_record_key()`. + */ + return b->update_index - a->update_index; +} + int reftable_log_record_equal(const struct reftable_log_record *a, const struct reftable_log_record *b, int hash_size) { @@ -1011,6 +1048,7 @@ static struct reftable_record_vtable reftable_log_record_vtable = { .release = &reftable_log_record_release_void, .is_deletion = &reftable_log_record_is_deletion_void, .equal = &reftable_log_record_equal_void, + .cmp = &reftable_log_record_cmp_void, .print = &reftable_log_record_print_void, }; @@ -1086,6 +1124,13 @@ static int reftable_index_record_equal(const void *a, const void *b, int hash_si return ia->offset == ib->offset && !strbuf_cmp(&ia->last_key, &ib->last_key); } +static int reftable_index_record_cmp(const void *_a, const void *_b) +{ + const struct reftable_index_record *a = _a; + const struct reftable_index_record *b = _b; + return strbuf_cmp(&a->last_key, &b->last_key); +} + static void reftable_index_record_print(const void *rec, int hash_size) { const struct reftable_index_record *idx = rec; @@ -1103,6 +1148,7 @@ static struct reftable_record_vtable reftable_index_record_vtable = { .release = &reftable_index_record_release, .is_deletion = ¬_a_deletion, .equal = &reftable_index_record_equal, + .cmp = &reftable_index_record_cmp, .print = &reftable_index_record_print, }; @@ -1156,6 +1202,14 @@ int reftable_record_is_deletion(struct reftable_record *rec) reftable_record_data(rec)); } +int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b) +{ + if (a->type != b->type) + BUG("cannot compare reftable records of different type"); + return reftable_record_vtable(a)->cmp( + reftable_record_data(a), reftable_record_data(b)); +} + int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size) { if (a->type != b->type) @@ -1164,7 +1218,7 @@ int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, reftable_record_data(a), reftable_record_data(b), hash_size); } -static int hash_equal(uint8_t *a, uint8_t *b, int hash_size) +static int hash_equal(const unsigned char *a, const unsigned char *b, int hash_size) { if (a && b) return !memcmp(a, b, hash_size); @@ -1266,45 +1320,22 @@ reftable_record_vtable(struct reftable_record *rec) abort(); } -struct reftable_record reftable_new_record(uint8_t typ) +void reftable_record_init(struct reftable_record *rec, uint8_t typ) { - struct reftable_record clean = { - .type = typ, - }; + memset(rec, 0, sizeof(*rec)); + rec->type = typ; - /* the following is involved, but the naive solution (just return - * `clean` as is, except for BLOCK_TYPE_INDEX), returns a garbage - * clean.u.obj.offsets pointer on Windows VS CI. Go figure. - */ switch (typ) { - case BLOCK_TYPE_OBJ: - { - struct reftable_obj_record obj = { 0 }; - clean.u.obj = obj; - break; - } - case BLOCK_TYPE_INDEX: - { - struct reftable_index_record idx = { - .last_key = STRBUF_INIT, - }; - clean.u.idx = idx; - break; - } case BLOCK_TYPE_REF: - { - struct reftable_ref_record ref = { 0 }; - clean.u.ref = ref; - break; - } case BLOCK_TYPE_LOG: - { - struct reftable_log_record log = { 0 }; - clean.u.log = log; - break; - } + case BLOCK_TYPE_OBJ: + return; + case BLOCK_TYPE_INDEX: + strbuf_init(&rec->u.idx.last_key, 0); + return; + default: + BUG("unhandled record type"); } - return clean; } void reftable_record_print(struct reftable_record *rec, int hash_size) diff --git a/reftable/record.h b/reftable/record.h index fd80cd451d..a05e2be179 100644 --- a/reftable/record.h +++ b/reftable/record.h @@ -62,6 +62,12 @@ struct reftable_record_vtable { /* Are two records equal? This assumes they have the same type. Returns 0 for non-equal. */ int (*equal)(const void *a, const void *b, int hash_size); + /* + * Compare keys of two records with each other. The records must have + * the same type. + */ + int (*cmp)(const void *a, const void *b); + /* Print on stdout, for debugging. */ void (*print)(const void *rec, int hash_size); }; @@ -69,9 +75,6 @@ struct reftable_record_vtable { /* returns true for recognized block types. Block start with the block type. */ int reftable_is_block_type(uint8_t typ); -/* return an initialized record for the given type */ -struct reftable_record reftable_new_record(uint8_t typ); - /* Encode `key` into `dest`. Sets `is_restart` to indicate a restart. Returns * number of bytes written. */ int reftable_encode_key(int *is_restart, struct string_view dest, @@ -100,8 +103,8 @@ struct reftable_obj_record { /* record is a generic wrapper for different types of records. It is normally * created on the stack, or embedded within another struct. If the type is * known, a fresh instance can be initialized explicitly. Otherwise, use - * reftable_new_record() to initialize generically (as the index_record is not - * valid as 0-initialized structure) + * `reftable_record_init()` to initialize generically (as the index_record is + * not valid as 0-initialized structure) */ struct reftable_record { uint8_t type; @@ -113,7 +116,11 @@ struct reftable_record { } u; }; +/* Initialize the reftable record for the given type */ +void reftable_record_init(struct reftable_record *rec, uint8_t typ); + /* see struct record_vtable */ +int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b); int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size); void reftable_record_print(struct reftable_record *rec, int hash_size); void reftable_record_key(struct reftable_record *rec, struct strbuf *dest); diff --git a/reftable/record_test.c b/reftable/record_test.c index 70ae78feca..a86cff5526 100644 --- a/reftable/record_test.c +++ b/reftable/record_test.c @@ -16,11 +16,11 @@ static void test_copy(struct reftable_record *rec) { - struct reftable_record copy = { 0 }; + struct reftable_record copy; uint8_t typ; typ = reftable_record_type(rec); - copy = reftable_new_record(typ); + reftable_record_init(©, typ); reftable_record_copy_from(©, rec, GIT_SHA1_RAWSZ); /* do it twice to catch memory leaks */ reftable_record_copy_from(©, rec, GIT_SHA1_RAWSZ); @@ -119,15 +119,10 @@ static void test_reftable_ref_record_roundtrip(void) case REFTABLE_REF_DELETION: break; case REFTABLE_REF_VAL1: - in.u.ref.value.val1 = reftable_malloc(GIT_SHA1_RAWSZ); set_hash(in.u.ref.value.val1, 1); break; case REFTABLE_REF_VAL2: - in.u.ref.value.val2.value = - reftable_malloc(GIT_SHA1_RAWSZ); set_hash(in.u.ref.value.val2.value, 1); - in.u.ref.value.val2.target_value = - reftable_malloc(GIT_SHA1_RAWSZ); set_hash(in.u.ref.value.val2.target_value, 2); break; case REFTABLE_REF_SYMREF: @@ -236,8 +231,8 @@ static void test_reftable_log_record_roundtrip(void) .value_type = REFTABLE_LOG_UPDATE, .value = { .update = { - .new_hash = reftable_calloc(GIT_SHA1_RAWSZ), - .old_hash = reftable_calloc(GIT_SHA1_RAWSZ), + .new_hash = reftable_calloc(GIT_SHA1_RAWSZ, 1), + .old_hash = reftable_calloc(GIT_SHA1_RAWSZ, 1), .name = xstrdup("old name"), .email = xstrdup("old@email"), .message = xstrdup("old message"), diff --git a/reftable/refname.c b/reftable/refname.c index 9573496932..7570e4acf9 100644 --- a/reftable/refname.c +++ b/reftable/refname.c @@ -140,8 +140,8 @@ int validate_ref_record_addition(struct reftable_table tab, { struct modification mod = { .tab = tab, - .add = reftable_calloc(sizeof(char *) * sz), - .del = reftable_calloc(sizeof(char *) * sz), + .add = reftable_calloc(sz, sizeof(*mod.add)), + .del = reftable_calloc(sz, sizeof(*mod.del)), }; int i = 0; int err = 0; diff --git a/reftable/refname_test.c b/reftable/refname_test.c index 8645cd93bb..b9cc62554e 100644 --- a/reftable/refname_test.c +++ b/reftable/refname_test.c @@ -9,7 +9,6 @@ https://developers.google.com/open-source/licenses/bsd #include "basics.h" #include "block.h" #include "blocksource.h" -#include "constants.h" #include "reader.h" #include "record.h" #include "refname.h" @@ -31,7 +30,7 @@ static void test_conflict(void) struct reftable_write_options opts = { 0 }; struct strbuf buf = STRBUF_INIT; struct reftable_writer *w = - reftable_new_writer(&strbuf_add_void, &buf, &opts); + reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts); struct reftable_ref_record rec = { .refname = "a/b", .value_type = REFTABLE_REF_SYMREF, diff --git a/reftable/reftable-merged.h b/reftable/reftable-merged.h index 1a6d16915a..c91a2d83a2 100644 --- a/reftable/reftable-merged.h +++ b/reftable/reftable-merged.h @@ -33,7 +33,7 @@ struct reftable_table; the stack array. */ int reftable_new_merged_table(struct reftable_merged_table **dest, - struct reftable_table *stack, int n, + struct reftable_table *stack, size_t n, uint32_t hash_id); /* returns an iterator positioned just before 'name' */ diff --git a/reftable/reftable-record.h b/reftable/reftable-record.h index 67104f8fbf..bb6e99acd3 100644 --- a/reftable/reftable-record.h +++ b/reftable/reftable-record.h @@ -9,6 +9,7 @@ https://developers.google.com/open-source/licenses/bsd #ifndef REFTABLE_RECORD_H #define REFTABLE_RECORD_H +#include "hash-ll.h" #include <stdint.h> /* @@ -38,10 +39,10 @@ struct reftable_ref_record { #define REFTABLE_NR_REF_VALUETYPES 4 } value_type; union { - uint8_t *val1; /* malloced hash. */ + unsigned char val1[GIT_MAX_RAWSZ]; struct { - uint8_t *value; /* first value, malloced hash */ - uint8_t *target_value; /* second value, malloced hash */ + unsigned char value[GIT_MAX_RAWSZ]; /* first hash */ + unsigned char target_value[GIT_MAX_RAWSZ]; /* second hash */ } val2; char *symref; /* referent, malloced 0-terminated string */ } value; @@ -49,11 +50,11 @@ struct reftable_ref_record { /* Returns the first hash, or NULL if `rec` is not of type * REFTABLE_REF_VAL1 or REFTABLE_REF_VAL2. */ -uint8_t *reftable_ref_record_val1(const struct reftable_ref_record *rec); +const unsigned char *reftable_ref_record_val1(const struct reftable_ref_record *rec); /* Returns the second hash, or NULL if `rec` is not of type * REFTABLE_REF_VAL2. */ -uint8_t *reftable_ref_record_val2(const struct reftable_ref_record *rec); +const unsigned char *reftable_ref_record_val2(const struct reftable_ref_record *rec); /* returns whether 'ref' represents a deletion */ int reftable_ref_record_is_deletion(const struct reftable_ref_record *ref); diff --git a/reftable/reftable-writer.h b/reftable/reftable-writer.h index db8de197f6..7c7cae5f99 100644 --- a/reftable/reftable-writer.h +++ b/reftable/reftable-writer.h @@ -88,6 +88,7 @@ struct reftable_stats { /* reftable_new_writer creates a new writer */ struct reftable_writer * reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t), + int (*flush_func)(void *), void *writer_arg, struct reftable_write_options *opts); /* Set the range of update indices for the records we will add. When writing a diff --git a/reftable/stack.c b/reftable/stack.c index ddbdf1b9c8..b64e55648a 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -8,6 +8,7 @@ https://developers.google.com/open-source/licenses/bsd #include "stack.h" +#include "../write-or-die.h" #include "system.h" #include "merged.h" #include "reader.h" @@ -16,13 +17,15 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable-record.h" #include "reftable-merged.h" #include "writer.h" +#include "tempfile.h" static int stack_try_add(struct reftable_stack *st, int (*write_table)(struct reftable_writer *wr, void *arg), void *arg); static int stack_write_compact(struct reftable_stack *st, - struct reftable_writer *wr, int first, int last, + struct reftable_writer *wr, + size_t first, size_t last, struct reftable_log_expiry_config *config); static int stack_check_addition(struct reftable_stack *st, const char *new_tab_name); @@ -42,14 +45,20 @@ static void stack_filename(struct strbuf *dest, struct reftable_stack *st, static ssize_t reftable_fd_write(void *arg, const void *data, size_t sz) { int *fdp = (int *)arg; - return write(*fdp, data, sz); + return write_in_full(*fdp, data, sz); +} + +static int reftable_fd_flush(void *arg) +{ + int *fdp = (int *)arg; + + return fsync_component(FSYNC_COMPONENT_REFERENCE, *fdp); } int reftable_new_stack(struct reftable_stack **dest, const char *dir, struct reftable_write_options config) { - struct reftable_stack *p = - reftable_calloc(sizeof(struct reftable_stack)); + struct reftable_stack *p = reftable_calloc(1, sizeof(*p)); struct strbuf list_file_name = STRBUF_INIT; int err = 0; @@ -64,6 +73,7 @@ int reftable_new_stack(struct reftable_stack **dest, const char *dir, strbuf_addstr(&list_file_name, "/tables.list"); p->list_file = strbuf_detach(&list_file_name, NULL); + p->list_fd = -1; p->reftable_dir = xstrdup(dir); p->config = config; @@ -91,8 +101,8 @@ static int fd_read_lines(int fd, char ***namesp) goto done; } - buf = reftable_malloc(size + 1); - if (read(fd, buf, size) != size) { + REFTABLE_ALLOC_ARRAY(buf, size + 1); + if (read_in_full(fd, buf, size) != size) { err = REFTABLE_IO_ERROR; goto done; } @@ -111,7 +121,7 @@ int read_lines(const char *filename, char ***namesp) int err = 0; if (fd < 0) { if (errno == ENOENT) { - *namesp = reftable_calloc(sizeof(char *)); + REFTABLE_CALLOC_ARRAY(*namesp, 1); return 0; } @@ -173,6 +183,12 @@ void reftable_stack_destroy(struct reftable_stack *st) st->readers_len = 0; FREE_AND_NULL(st->readers); } + + if (st->list_fd >= 0) { + close(st->list_fd); + st->list_fd = -1; + } + FREE_AND_NULL(st->list_file); FREE_AND_NULL(st->reftable_dir); reftable_free(st); @@ -182,8 +198,7 @@ void reftable_stack_destroy(struct reftable_stack *st) static struct reftable_reader **stack_copy_readers(struct reftable_stack *st, int cur_len) { - struct reftable_reader **cur = - reftable_calloc(sizeof(struct reftable_reader *) * cur_len); + struct reftable_reader **cur = reftable_calloc(cur_len, sizeof(*cur)); int i = 0; for (i = 0; i < cur_len; i++) { cur[i] = st->readers[i]; @@ -194,17 +209,18 @@ static struct reftable_reader **stack_copy_readers(struct reftable_stack *st, static int reftable_stack_reload_once(struct reftable_stack *st, char **names, int reuse_open) { - int cur_len = !st->merged ? 0 : st->merged->stack_len; + size_t cur_len = !st->merged ? 0 : st->merged->stack_len; struct reftable_reader **cur = stack_copy_readers(st, cur_len); - int err = 0; - int names_len = names_length(names); + size_t names_len = names_length(names); struct reftable_reader **new_readers = - reftable_calloc(sizeof(struct reftable_reader *) * names_len); + reftable_calloc(names_len, sizeof(*new_readers)); struct reftable_table *new_tables = - reftable_calloc(sizeof(struct reftable_table) * names_len); - int new_readers_len = 0; + reftable_calloc(names_len, sizeof(*new_tables)); + size_t new_readers_len = 0; struct reftable_merged_table *new_merged = NULL; - int i; + struct strbuf table_path = STRBUF_INIT; + int err = 0; + size_t i; while (*names) { struct reftable_reader *rd = NULL; @@ -212,24 +228,20 @@ static int reftable_stack_reload_once(struct reftable_stack *st, char **names, /* this is linear; we assume compaction keeps the number of tables under control so this is not quadratic. */ - int j = 0; - for (j = 0; reuse_open && j < cur_len; j++) { - if (cur[j] && 0 == strcmp(cur[j]->name, name)) { - rd = cur[j]; - cur[j] = NULL; + for (i = 0; reuse_open && i < cur_len; i++) { + if (cur[i] && 0 == strcmp(cur[i]->name, name)) { + rd = cur[i]; + cur[i] = NULL; break; } } if (!rd) { struct reftable_block_source src = { NULL }; - struct strbuf table_path = STRBUF_INIT; stack_filename(&table_path, st, name); err = reftable_block_source_from_file(&src, table_path.buf); - strbuf_release(&table_path); - if (err < 0) goto done; @@ -267,16 +279,13 @@ static int reftable_stack_reload_once(struct reftable_stack *st, char **names, for (i = 0; i < cur_len; i++) { if (cur[i]) { const char *name = reader_name(cur[i]); - struct strbuf filename = STRBUF_INIT; - stack_filename(&filename, st, name); + stack_filename(&table_path, st, name); reader_close(cur[i]); reftable_reader_free(cur[i]); /* On Windows, can only unlink after closing. */ - unlink(filename.buf); - - strbuf_release(&filename); + unlink(table_path.buf); } } @@ -288,6 +297,7 @@ done: reftable_free(new_readers); reftable_free(new_tables); reftable_free(cur); + strbuf_release(&table_path); return err; } @@ -306,69 +316,134 @@ static int tv_cmp(struct timeval *a, struct timeval *b) static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, int reuse_open) { - struct timeval deadline = { 0 }; - int err = gettimeofday(&deadline, NULL); + char **names = NULL, **names_after = NULL; + struct timeval deadline; int64_t delay = 0; - int tries = 0; - if (err < 0) - return err; + int tries = 0, err; + int fd = -1; + err = gettimeofday(&deadline, NULL); + if (err < 0) + goto out; deadline.tv_sec += 3; + while (1) { - char **names = NULL; - char **names_after = NULL; - struct timeval now = { 0 }; - int err = gettimeofday(&now, NULL); - int err2 = 0; - if (err < 0) { - return err; - } + struct timeval now; - /* Only look at deadlines after the first few times. This - simplifies debugging in GDB */ + err = gettimeofday(&now, NULL); + if (err < 0) + goto out; + + /* + * Only look at deadlines after the first few times. This + * simplifies debugging in GDB. + */ tries++; - if (tries > 3 && tv_cmp(&now, &deadline) >= 0) { - break; - } + if (tries > 3 && tv_cmp(&now, &deadline) >= 0) + goto out; - err = read_lines(st->list_file, &names); - if (err < 0) { - free_names(names); - return err; - } - err = reftable_stack_reload_once(st, names, reuse_open); - if (err == 0) { - free_names(names); - break; - } - if (err != REFTABLE_NOT_EXIST_ERROR) { - free_names(names); - return err; - } + fd = open(st->list_file, O_RDONLY); + if (fd < 0) { + if (errno != ENOENT) { + err = REFTABLE_IO_ERROR; + goto out; + } - /* err == REFTABLE_NOT_EXIST_ERROR can be caused by a concurrent - writer. Check if there was one by checking if the name list - changed. - */ - err2 = read_lines(st->list_file, &names_after); - if (err2 < 0) { - free_names(names); - return err2; + REFTABLE_CALLOC_ARRAY(names, 1); + } else { + err = fd_read_lines(fd, &names); + if (err < 0) + goto out; } + err = reftable_stack_reload_once(st, names, reuse_open); + if (!err) + break; + if (err != REFTABLE_NOT_EXIST_ERROR) + goto out; + + /* + * REFTABLE_NOT_EXIST_ERROR can be caused by a concurrent + * writer. Check if there was one by checking if the name list + * changed. + */ + err = read_lines(st->list_file, &names_after); + if (err < 0) + goto out; if (names_equal(names_after, names)) { - free_names(names); - free_names(names_after); - return err; + err = REFTABLE_NOT_EXIST_ERROR; + goto out; } + free_names(names); + names = NULL; free_names(names_after); + names_after = NULL; + close(fd); + fd = -1; delay = delay + (delay * rand()) / RAND_MAX + 1; sleep_millisec(delay); } - return 0; +out: + /* + * Invalidate the stat cache. It is sufficient to only close the file + * descriptor and keep the cached stat info because we never use the + * latter when the former is negative. + */ + if (st->list_fd >= 0) { + close(st->list_fd); + st->list_fd = -1; + } + + /* + * Cache stat information in case it provides a useful signal to us. + * According to POSIX, "The st_ino and st_dev fields taken together + * uniquely identify the file within the system." That being said, + * Windows is not POSIX compliant and we do not have these fields + * available. So the information we have there is insufficient to + * determine whether two file descriptors point to the same file. + * + * While we could fall back to using other signals like the file's + * mtime, those are not sufficient to avoid races. We thus refrain from + * using the stat cache on such systems and fall back to the secondary + * caching mechanism, which is to check whether contents of the file + * have changed. + * + * On other systems which are POSIX compliant we must keep the file + * descriptor open. This is to avoid a race condition where two + * processes access the reftable stack at the same point in time: + * + * 1. A reads the reftable stack and caches its stat info. + * + * 2. B updates the stack, appending a new table to "tables.list". + * This will both use a new inode and result in a different file + * size, thus invalidating A's cache in theory. + * + * 3. B decides to auto-compact the stack and merges two tables. The + * file size now matches what A has cached again. Furthermore, the + * filesystem may decide to recycle the inode number of the file + * we have replaced in (2) because it is not in use anymore. + * + * 4. A reloads the reftable stack. Neither the inode number nor the + * file size changed. If the timestamps did not change either then + * we think the cached copy of our stack is up-to-date. + * + * By keeping the file descriptor open the inode number cannot be + * recycled, mitigating the race. + */ + if (!err && fd >= 0 && !fstat(fd, &st->list_st) && + st->list_st.st_dev && st->list_st.st_ino) { + st->list_fd = fd; + fd = -1; + } + + if (fd >= 0) + close(fd); + free_names(names); + free_names(names_after); + return err; } /* -1 = error @@ -377,8 +452,44 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, static int stack_uptodate(struct reftable_stack *st) { char **names = NULL; - int err = read_lines(st->list_file, &names); + int err; int i = 0; + + /* + * When we have cached stat information available then we use it to + * verify whether the file has been rewritten. + * + * Note that we explicitly do not want to use `stat_validity_check()` + * and friends here because they may end up not comparing the `st_dev` + * and `st_ino` fields. These functions thus cannot guarantee that we + * indeed still have the same file. + */ + if (st->list_fd >= 0) { + struct stat list_st; + + if (stat(st->list_file, &list_st) < 0) { + /* + * It's fine for "tables.list" to not exist. In that + * case, we have to refresh when the loaded stack has + * any readers. + */ + if (errno == ENOENT) + return !!st->readers_len; + return REFTABLE_IO_ERROR; + } + + /* + * When "tables.list" refers to the same file we can assume + * that it didn't change. This is because we always use + * rename(3P) to update the file and never write to it + * directly. + */ + if (st->list_st.st_dev == list_st.st_dev && + st->list_st.st_ino == list_st.st_ino) + return 0; + } + + err = read_lines(st->list_file, &names); if (err < 0) return err; @@ -427,16 +538,13 @@ int reftable_stack_add(struct reftable_stack *st, return err; } - if (!st->disable_auto_compact) - return reftable_stack_auto_compact(st); - return 0; } static void format_name(struct strbuf *dest, uint64_t min, uint64_t max) { char buf[100]; - uint32_t rnd = (uint32_t)rand(); + uint32_t rnd = (uint32_t)git_rand(); snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x", min, max, rnd); strbuf_reset(dest); @@ -444,33 +552,27 @@ static void format_name(struct strbuf *dest, uint64_t min, uint64_t max) } struct reftable_addition { - int lock_file_fd; - struct strbuf lock_file_name; + struct tempfile *lock_file; struct reftable_stack *stack; char **new_tables; - int new_tables_len; + size_t new_tables_len, new_tables_cap; uint64_t next_update_index; }; -#define REFTABLE_ADDITION_INIT \ - { \ - .lock_file_name = STRBUF_INIT \ - } +#define REFTABLE_ADDITION_INIT {0} static int reftable_stack_init_addition(struct reftable_addition *add, struct reftable_stack *st) { + struct strbuf lock_file_name = STRBUF_INIT; int err = 0; add->stack = st; - strbuf_reset(&add->lock_file_name); - strbuf_addstr(&add->lock_file_name, st->list_file); - strbuf_addstr(&add->lock_file_name, ".lock"); + strbuf_addf(&lock_file_name, "%s.lock", st->list_file); - add->lock_file_fd = open(add->lock_file_name.buf, - O_EXCL | O_CREAT | O_WRONLY, 0666); - if (add->lock_file_fd < 0) { + add->lock_file = create_tempfile(lock_file_name.buf); + if (!add->lock_file) { if (errno == EEXIST) { err = REFTABLE_LOCK_ERROR; } else { @@ -479,7 +581,7 @@ static int reftable_stack_init_addition(struct reftable_addition *add, goto done; } if (st->config.default_permissions) { - if (chmod(add->lock_file_name.buf, st->config.default_permissions) < 0) { + if (chmod(add->lock_file->filename.buf, st->config.default_permissions) < 0) { err = REFTABLE_IO_ERROR; goto done; } @@ -499,13 +601,15 @@ done: if (err) { reftable_addition_close(add); } + strbuf_release(&lock_file_name); return err; } static void reftable_addition_close(struct reftable_addition *add) { - int i = 0; struct strbuf nm = STRBUF_INIT; + size_t i; + for (i = 0; i < add->new_tables_len; i++) { stack_filename(&nm, add->stack, add->new_tables[i]); unlink(nm.buf); @@ -515,16 +619,9 @@ static void reftable_addition_close(struct reftable_addition *add) reftable_free(add->new_tables); add->new_tables = NULL; add->new_tables_len = 0; + add->new_tables_cap = 0; - if (add->lock_file_fd > 0) { - close(add->lock_file_fd); - add->lock_file_fd = 0; - } - if (add->lock_file_name.len > 0) { - unlink(add->lock_file_name.buf); - strbuf_release(&add->lock_file_name); - } - + delete_tempfile(&add->lock_file); strbuf_release(&nm); } @@ -540,8 +637,10 @@ void reftable_addition_destroy(struct reftable_addition *add) int reftable_addition_commit(struct reftable_addition *add) { struct strbuf table_list = STRBUF_INIT; - int i = 0; + int lock_file_fd = get_tempfile_fd(add->lock_file); int err = 0; + size_t i; + if (add->new_tables_len == 0) goto done; @@ -554,36 +653,37 @@ int reftable_addition_commit(struct reftable_addition *add) strbuf_addstr(&table_list, "\n"); } - err = write(add->lock_file_fd, table_list.buf, table_list.len); + err = write_in_full(lock_file_fd, table_list.buf, table_list.len); strbuf_release(&table_list); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; } - err = close(add->lock_file_fd); - add->lock_file_fd = 0; - if (err < 0) { - err = REFTABLE_IO_ERROR; - goto done; - } + fsync_component_or_die(FSYNC_COMPONENT_REFERENCE, lock_file_fd, + get_tempfile_path(add->lock_file)); - err = rename(add->lock_file_name.buf, add->stack->list_file); + err = rename_tempfile(&add->lock_file, add->stack->list_file); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; } /* success, no more state to clean up. */ - strbuf_release(&add->lock_file_name); - for (i = 0; i < add->new_tables_len; i++) { + for (i = 0; i < add->new_tables_len; i++) reftable_free(add->new_tables[i]); - } reftable_free(add->new_tables); add->new_tables = NULL; add->new_tables_len = 0; + add->new_tables_cap = 0; + + err = reftable_stack_reload_maybe_reuse(add->stack, 1); + if (err) + goto done; + + if (!add->stack->disable_auto_compact) + err = reftable_stack_auto_compact(add->stack); - err = reftable_stack_reload(add->stack); done: reftable_addition_close(add); return err; @@ -594,7 +694,7 @@ int reftable_stack_new_addition(struct reftable_addition **dest, { int err = 0; struct reftable_addition empty = REFTABLE_ADDITION_INIT; - *dest = reftable_calloc(sizeof(**dest)); + REFTABLE_CALLOC_ARRAY(*dest, 1); **dest = empty; err = reftable_stack_init_addition(*dest, st); if (err) { @@ -657,7 +757,7 @@ int reftable_addition_add(struct reftable_addition *add, goto done; } } - wr = reftable_new_writer(reftable_fd_write, &tab_fd, + wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush, &tab_fd, &add->stack->config); err = write_table(wr, arg); if (err < 0) @@ -702,11 +802,9 @@ int reftable_addition_add(struct reftable_addition *add, goto done; } - add->new_tables = reftable_realloc(add->new_tables, - sizeof(*add->new_tables) * - (add->new_tables_len + 1)); - add->new_tables[add->new_tables_len] = strbuf_detach(&next_name, NULL); - add->new_tables_len++; + REFTABLE_ALLOC_GROW(add->new_tables, add->new_tables_len + 1, + add->new_tables_cap); + add->new_tables[add->new_tables_len++] = strbuf_detach(&next_name, NULL); done: if (tab_fd > 0) { close(tab_fd); @@ -732,7 +830,8 @@ uint64_t reftable_stack_next_update_index(struct reftable_stack *st) return 1; } -static int stack_compact_locked(struct reftable_stack *st, int first, int last, +static int stack_compact_locked(struct reftable_stack *st, + size_t first, size_t last, struct strbuf *temp_tab, struct reftable_log_expiry_config *config) { @@ -749,7 +848,13 @@ static int stack_compact_locked(struct reftable_stack *st, int first, int last, strbuf_addstr(temp_tab, ".temp.XXXXXX"); tab_fd = mkstemp(temp_tab->buf); - wr = reftable_new_writer(reftable_fd_write, &tab_fd, &st->config); + if (st->config.default_permissions && + chmod(temp_tab->buf, st->config.default_permissions) < 0) { + err = REFTABLE_IO_ERROR; + goto done; + } + + wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush, &tab_fd, &st->config); err = stack_write_compact(st, wr, first, last, config); if (err < 0) @@ -776,22 +881,21 @@ done: } static int stack_write_compact(struct reftable_stack *st, - struct reftable_writer *wr, int first, int last, + struct reftable_writer *wr, + size_t first, size_t last, struct reftable_log_expiry_config *config) { - int subtabs_len = last - first + 1; + size_t subtabs_len = last - first + 1; struct reftable_table *subtabs = reftable_calloc( - sizeof(struct reftable_table) * (last - first + 1)); + last - first + 1, sizeof(*subtabs)); struct reftable_merged_table *mt = NULL; - int err = 0; struct reftable_iterator it = { NULL }; struct reftable_ref_record ref = { NULL }; struct reftable_log_record log = { NULL }; - uint64_t entries = 0; + int err = 0; - int i = 0, j = 0; - for (i = first, j = 0; i <= last; i++) { + for (size_t i = first, j = 0; i <= last; i++) { struct reftable_reader *t = st->readers[i]; reftable_table_from_reader(&subtabs[j++], t); st->stats.bytes += t->size; @@ -816,18 +920,16 @@ static int stack_write_compact(struct reftable_stack *st, err = 0; break; } - if (err < 0) { - break; - } + if (err < 0) + goto done; if (first == 0 && reftable_ref_record_is_deletion(&ref)) { continue; } err = reftable_writer_add_ref(wr, &ref); - if (err < 0) { - break; - } + if (err < 0) + goto done; entries++; } reftable_iterator_destroy(&it); @@ -842,9 +944,8 @@ static int stack_write_compact(struct reftable_stack *st, err = 0; break; } - if (err < 0) { - break; - } + if (err < 0) + goto done; if (first == 0 && reftable_log_record_is_deletion(&log)) { continue; } @@ -860,9 +961,8 @@ static int stack_write_compact(struct reftable_stack *st, } err = reftable_writer_add_log(wr, &log); - if (err < 0) { - break; - } + if (err < 0) + goto done; entries++; } @@ -879,25 +979,20 @@ done: } /* < 0: error. 0 == OK, > 0 attempt failed; could retry. */ -static int stack_compact_range(struct reftable_stack *st, int first, int last, +static int stack_compact_range(struct reftable_stack *st, + size_t first, size_t last, struct reftable_log_expiry_config *expiry) { + char **delete_on_success = NULL, **subtable_locks = NULL, **listp = NULL; struct strbuf temp_tab_file_name = STRBUF_INIT; struct strbuf new_table_name = STRBUF_INIT; struct strbuf lock_file_name = STRBUF_INIT; struct strbuf ref_list_contents = STRBUF_INIT; struct strbuf new_table_path = STRBUF_INIT; + size_t i, j, compact_count; int err = 0; int have_lock = 0; int lock_file_fd = -1; - int compact_count = last - first + 1; - char **listp = NULL; - char **delete_on_success = - reftable_calloc(sizeof(char *) * (compact_count + 1)); - char **subtable_locks = - reftable_calloc(sizeof(char *) * (compact_count + 1)); - int i = 0; - int j = 0; int is_empty_table = 0; if (first > last || (!expiry && first == last)) { @@ -905,6 +1000,10 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last, goto done; } + compact_count = last - first + 1; + REFTABLE_CALLOC_ARRAY(delete_on_success, compact_count + 1); + REFTABLE_CALLOC_ARRAY(subtable_locks, compact_count + 1); + st->stats.attempts++; strbuf_reset(&lock_file_name); @@ -1024,12 +1123,20 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last, strbuf_addstr(&ref_list_contents, "\n"); } - err = write(lock_file_fd, ref_list_contents.buf, ref_list_contents.len); + err = write_in_full(lock_file_fd, ref_list_contents.buf, ref_list_contents.len); if (err < 0) { err = REFTABLE_IO_ERROR; unlink(new_table_path.buf); goto done; } + + err = fsync_component(FSYNC_COMPONENT_REFERENCE, lock_file_fd); + if (err < 0) { + err = REFTABLE_IO_ERROR; + unlink(new_table_path.buf); + goto done; + } + err = close(lock_file_fd); lock_file_fd = -1; if (err < 0) { @@ -1062,12 +1169,14 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last, done: free_names(delete_on_success); - listp = subtable_locks; - while (*listp) { - unlink(*listp); - listp++; + if (subtable_locks) { + listp = subtable_locks; + while (*listp) { + unlink(*listp); + listp++; + } + free_names(subtable_locks); } - free_names(subtable_locks); if (lock_file_fd >= 0) { close(lock_file_fd); lock_file_fd = -1; @@ -1086,17 +1195,17 @@ done: int reftable_stack_compact_all(struct reftable_stack *st, struct reftable_log_expiry_config *config) { - return stack_compact_range(st, 0, st->merged->stack_len - 1, config); + return stack_compact_range(st, 0, st->merged->stack_len ? + st->merged->stack_len - 1 : 0, config); } -static int stack_compact_range_stats(struct reftable_stack *st, int first, - int last, +static int stack_compact_range_stats(struct reftable_stack *st, + size_t first, size_t last, struct reftable_log_expiry_config *config) { int err = stack_compact_range(st, first, last, config); - if (err > 0) { + if (err > 0) st->stats.failures++; - } return err; } @@ -1116,12 +1225,11 @@ int fastlog2(uint64_t sz) return l - 1; } -struct segment *sizes_to_segments(int *seglen, uint64_t *sizes, int n) +struct segment *sizes_to_segments(size_t *seglen, uint64_t *sizes, size_t n) { - struct segment *segs = reftable_calloc(sizeof(struct segment) * n); - int next = 0; + struct segment *segs = reftable_calloc(n, sizeof(*segs)); struct segment cur = { 0 }; - int i = 0; + size_t next = 0, i; if (n == 0) { *seglen = 0; @@ -1147,29 +1255,27 @@ struct segment *sizes_to_segments(int *seglen, uint64_t *sizes, int n) return segs; } -struct segment suggest_compaction_segment(uint64_t *sizes, int n) +struct segment suggest_compaction_segment(uint64_t *sizes, size_t n) { - int seglen = 0; - struct segment *segs = sizes_to_segments(&seglen, sizes, n); struct segment min_seg = { .log = 64, }; - int i = 0; + struct segment *segs; + size_t seglen = 0, i; + + segs = sizes_to_segments(&seglen, sizes, n); for (i = 0; i < seglen; i++) { - if (segment_size(&segs[i]) == 1) { + if (segment_size(&segs[i]) == 1) continue; - } - if (segs[i].log < min_seg.log) { + if (segs[i].log < min_seg.log) min_seg = segs[i]; - } } while (min_seg.start > 0) { - int prev = min_seg.start - 1; - if (fastlog2(min_seg.bytes) < fastlog2(sizes[prev])) { + size_t prev = min_seg.start - 1; + if (fastlog2(min_seg.bytes) < fastlog2(sizes[prev])) break; - } min_seg.start = prev; min_seg.bytes += sizes[prev]; @@ -1182,7 +1288,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, int n) static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st) { uint64_t *sizes = - reftable_calloc(sizeof(uint64_t) * st->merged->stack_len); + reftable_calloc(st->merged->stack_len, sizeof(*sizes)); int version = (st->config.hash_id == GIT_SHA1_FORMAT_ID) ? 1 : 2; int overhead = header_size(version) - 1; int i = 0; @@ -1281,17 +1387,12 @@ static int stack_check_addition(struct reftable_stack *st, while (1) { struct reftable_ref_record ref = { NULL }; err = reftable_iterator_next_ref(&it, &ref); - if (err > 0) { + if (err > 0) break; - } if (err < 0) goto done; - if (len >= cap) { - cap = 2 * cap + 1; - refs = reftable_realloc(refs, cap * sizeof(refs[0])); - } - + REFTABLE_ALLOC_GROW(refs, len + 1, cap); refs[len++] = ref; } diff --git a/reftable/stack.h b/reftable/stack.h index f57005846e..d919455669 100644 --- a/reftable/stack.h +++ b/reftable/stack.h @@ -14,7 +14,10 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable-stack.h" struct reftable_stack { + struct stat list_st; char *list_file; + int list_fd; + char *reftable_dir; int disable_auto_compact; @@ -29,13 +32,13 @@ struct reftable_stack { int read_lines(const char *filename, char ***lines); struct segment { - int start, end; + size_t start, end; int log; uint64_t bytes; }; int fastlog2(uint64_t sz); -struct segment *sizes_to_segments(int *seglen, uint64_t *sizes, int n); -struct segment suggest_compaction_segment(uint64_t *sizes, int n); +struct segment *sizes_to_segments(size_t *seglen, uint64_t *sizes, size_t n); +struct segment suggest_compaction_segment(uint64_t *sizes, size_t n); #endif diff --git a/reftable/stack_test.c b/reftable/stack_test.c index d0b717510f..509f486623 100644 --- a/reftable/stack_test.c +++ b/reftable/stack_test.c @@ -13,7 +13,6 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable-reader.h" #include "merged.h" #include "basics.h" -#include "constants.h" #include "record.h" #include "test_framework.h" #include "reftable-tests.h" @@ -78,7 +77,7 @@ static void test_read_file(void) int i = 0; EXPECT(fd > 0); - n = write(fd, out, strlen(out)); + n = write_in_full(fd, out, strlen(out)); EXPECT(n == strlen(out)); err = close(fd); EXPECT(err >= 0); @@ -289,6 +288,61 @@ static void test_reftable_stack_transaction_api(void) clear_dir(dir); } +static void test_reftable_stack_transaction_api_performs_auto_compaction(void) +{ + char *dir = get_tmp_dir(__LINE__); + struct reftable_write_options cfg = {0}; + struct reftable_addition *add = NULL; + struct reftable_stack *st = NULL; + int i, n = 20, err; + + err = reftable_new_stack(&st, dir, cfg); + EXPECT_ERR(err); + + for (i = 0; i <= n; i++) { + struct reftable_ref_record ref = { + .update_index = reftable_stack_next_update_index(st), + .value_type = REFTABLE_REF_SYMREF, + .value.symref = "master", + }; + char name[100]; + + snprintf(name, sizeof(name), "branch%04d", i); + ref.refname = name; + + /* + * Disable auto-compaction for all but the last runs. Like this + * we can ensure that we indeed honor this setting and have + * better control over when exactly auto compaction runs. + */ + st->disable_auto_compact = i != n; + + err = reftable_stack_new_addition(&add, st); + EXPECT_ERR(err); + + err = reftable_addition_add(add, &write_test_ref, &ref); + EXPECT_ERR(err); + + err = reftable_addition_commit(add); + EXPECT_ERR(err); + + reftable_addition_destroy(add); + + /* + * The stack length should grow continuously for all runs where + * auto compaction is disabled. When enabled, we should merge + * all tables in the stack. + */ + if (i != n) + EXPECT(st->merged->stack_len == i + 1); + else + EXPECT(st->merged->stack_len == 1); + } + + reftable_stack_destroy(st); + clear_dir(dir); +} + static void test_reftable_stack_validate_refname(void) { struct reftable_write_options cfg = { 0 }; @@ -389,15 +443,16 @@ static void test_reftable_stack_add(void) int err = 0; struct reftable_write_options cfg = { .exact_log_message = 1, + .default_permissions = 0660, }; struct reftable_stack *st = NULL; char *dir = get_tmp_dir(__LINE__); - struct reftable_ref_record refs[2] = { { NULL } }; struct reftable_log_record logs[2] = { { NULL } }; + struct strbuf path = STRBUF_INIT; + struct stat stat_result; int N = ARRAY_SIZE(refs); - err = reftable_new_stack(&st, dir, cfg); EXPECT_ERR(err); st->disable_auto_compact = 1; @@ -408,7 +463,6 @@ static void test_reftable_stack_add(void) refs[i].refname = xstrdup(buf); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - refs[i].value.val1 = reftable_malloc(GIT_SHA1_RAWSZ); set_test_hash(refs[i].value.val1, i); logs[i].refname = xstrdup(buf); @@ -456,12 +510,32 @@ static void test_reftable_stack_add(void) reftable_log_record_release(&dest); } +#ifndef GIT_WINDOWS_NATIVE + strbuf_addstr(&path, dir); + strbuf_addstr(&path, "/tables.list"); + err = stat(path.buf, &stat_result); + EXPECT(!err); + EXPECT((stat_result.st_mode & 0777) == cfg.default_permissions); + + strbuf_reset(&path); + strbuf_addstr(&path, dir); + strbuf_addstr(&path, "/"); + /* do not try at home; not an external API for reftable. */ + strbuf_addstr(&path, st->readers[0]->name); + err = stat(path.buf, &stat_result); + EXPECT(!err); + EXPECT((stat_result.st_mode & 0777) == cfg.default_permissions); +#else + (void) stat_result; +#endif + /* cleanup */ reftable_stack_destroy(st); for (i = 0; i < N; i++) { reftable_ref_record_release(&refs[i]); reftable_log_record_release(&logs[i]); } + strbuf_release(&path); clear_dir(dir); } @@ -545,7 +619,6 @@ static void test_reftable_stack_tombstone(void) refs[i].update_index = i + 1; if (i % 2 == 0) { refs[i].value_type = REFTABLE_REF_VAL1; - refs[i].value.val1 = reftable_malloc(GIT_SHA1_RAWSZ); set_test_hash(refs[i].value.val1, i); } @@ -659,7 +732,7 @@ static void test_sizes_to_segments(void) uint64_t sizes[] = { 2, 3, 4, 5, 7, 9 }; /* .................0 1 2 3 4 5 */ - int seglen = 0; + size_t seglen = 0; struct segment *segs = sizes_to_segments(&seglen, sizes, ARRAY_SIZE(sizes)); EXPECT(segs[2].log == 3); @@ -674,7 +747,7 @@ static void test_sizes_to_segments(void) static void test_sizes_to_segments_empty(void) { - int seglen = 0; + size_t seglen = 0; struct segment *segs = sizes_to_segments(&seglen, NULL, 0); EXPECT(seglen == 0); reftable_free(segs); @@ -683,8 +756,7 @@ static void test_sizes_to_segments_empty(void) static void test_sizes_to_segments_all_equal(void) { uint64_t sizes[] = { 5, 5 }; - - int seglen = 0; + size_t seglen = 0; struct segment *segs = sizes_to_segments(&seglen, sizes, ARRAY_SIZE(sizes)); EXPECT(seglen == 1); @@ -850,6 +922,54 @@ static void test_reftable_stack_auto_compaction(void) clear_dir(dir); } +static void test_reftable_stack_add_performs_auto_compaction(void) +{ + struct reftable_write_options cfg = { 0 }; + struct reftable_stack *st = NULL; + struct strbuf refname = STRBUF_INIT; + char *dir = get_tmp_dir(__LINE__); + int err, i, n = 20; + + err = reftable_new_stack(&st, dir, cfg); + EXPECT_ERR(err); + + for (i = 0; i <= n; i++) { + struct reftable_ref_record ref = { + .update_index = reftable_stack_next_update_index(st), + .value_type = REFTABLE_REF_SYMREF, + .value.symref = "master", + }; + + /* + * Disable auto-compaction for all but the last runs. Like this + * we can ensure that we indeed honor this setting and have + * better control over when exactly auto compaction runs. + */ + st->disable_auto_compact = i != n; + + strbuf_reset(&refname); + strbuf_addf(&refname, "branch-%04d", i); + ref.refname = refname.buf; + + err = reftable_stack_add(st, &write_test_ref, &ref); + EXPECT_ERR(err); + + /* + * The stack length should grow continuously for all runs where + * auto compaction is disabled. When enabled, we should merge + * all tables in the stack. + */ + if (i != n) + EXPECT(st->merged->stack_len == i + 1); + else + EXPECT(st->merged->stack_len == 1); + } + + reftable_stack_destroy(st); + strbuf_release(&refname); + clear_dir(dir); +} + static void test_reftable_stack_compaction_concurrent(void) { struct reftable_write_options cfg = { 0 }; @@ -960,6 +1080,7 @@ int stack_test_main(int argc, const char *argv[]) RUN_TEST(test_reftable_stack_add); RUN_TEST(test_reftable_stack_add_one); RUN_TEST(test_reftable_stack_auto_compaction); + RUN_TEST(test_reftable_stack_add_performs_auto_compaction); RUN_TEST(test_reftable_stack_compaction_concurrent); RUN_TEST(test_reftable_stack_compaction_concurrent_clean); RUN_TEST(test_reftable_stack_hash_id); @@ -967,6 +1088,7 @@ int stack_test_main(int argc, const char *argv[]) RUN_TEST(test_reftable_stack_log_normalize); RUN_TEST(test_reftable_stack_tombstone); RUN_TEST(test_reftable_stack_transaction_api); + RUN_TEST(test_reftable_stack_transaction_api_performs_auto_compaction); RUN_TEST(test_reftable_stack_update_index_check); RUN_TEST(test_reftable_stack_uptodate); RUN_TEST(test_reftable_stack_validate_refname); diff --git a/reftable/test_framework.c b/reftable/test_framework.c index 84ac972cad..4066924eee 100644 --- a/reftable/test_framework.c +++ b/reftable/test_framework.c @@ -9,7 +9,6 @@ https://developers.google.com/open-source/licenses/bsd #include "system.h" #include "test_framework.h" -#include "basics.h" void set_test_hash(uint8_t *p, int i) { @@ -21,3 +20,8 @@ ssize_t strbuf_add_void(void *b, const void *data, size_t sz) strbuf_add(b, data, sz); return sz; } + +int noop_flush(void *arg) +{ + return 0; +} diff --git a/reftable/test_framework.h b/reftable/test_framework.h index 774cb275bf..687390f9c2 100644 --- a/reftable/test_framework.h +++ b/reftable/test_framework.h @@ -12,32 +12,38 @@ https://developers.google.com/open-source/licenses/bsd #include "system.h" #include "reftable-error.h" -#define EXPECT_ERR(c) \ - if (c != 0) { \ - fflush(stderr); \ - fflush(stdout); \ - fprintf(stderr, "%s: %d: error == %d (%s), want 0\n", \ - __FILE__, __LINE__, c, reftable_error_str(c)); \ - abort(); \ - } - -#define EXPECT_STREQ(a, b) \ - if (strcmp(a, b)) { \ - fflush(stderr); \ - fflush(stdout); \ - fprintf(stderr, "%s:%d: %s (%s) != %s (%s)\n", __FILE__, \ - __LINE__, #a, a, #b, b); \ - abort(); \ - } - -#define EXPECT(c) \ - if (!(c)) { \ - fflush(stderr); \ - fflush(stdout); \ - fprintf(stderr, "%s: %d: failed assertion %s\n", __FILE__, \ - __LINE__, #c); \ - abort(); \ - } +#define EXPECT_ERR(c) \ + do { \ + if (c != 0) { \ + fflush(stderr); \ + fflush(stdout); \ + fprintf(stderr, "%s: %d: error == %d (%s), want 0\n", \ + __FILE__, __LINE__, c, reftable_error_str(c)); \ + abort(); \ + } \ + } while (0) + +#define EXPECT_STREQ(a, b) \ + do { \ + if (strcmp(a, b)) { \ + fflush(stderr); \ + fflush(stdout); \ + fprintf(stderr, "%s:%d: %s (%s) != %s (%s)\n", __FILE__, \ + __LINE__, #a, a, #b, b); \ + abort(); \ + } \ + } while (0) + +#define EXPECT(c) \ + do { \ + if (!(c)) { \ + fflush(stderr); \ + fflush(stdout); \ + fprintf(stderr, "%s: %d: failed assertion %s\n", __FILE__, \ + __LINE__, #c); \ + abort(); \ + } \ + } while (0) #define RUN_TEST(f) \ fprintf(stderr, "running %s\n", #f); \ @@ -50,4 +56,6 @@ void set_test_hash(uint8_t *p, int i); */ ssize_t strbuf_add_void(void *b, const void *data, size_t sz); +int noop_flush(void *); + #endif diff --git a/reftable/tree.c b/reftable/tree.c index a5bf880985..528f33ae38 100644 --- a/reftable/tree.c +++ b/reftable/tree.c @@ -20,8 +20,8 @@ struct tree_node *tree_search(void *key, struct tree_node **rootp, if (!insert) { return NULL; } else { - struct tree_node *n = - reftable_calloc(sizeof(struct tree_node)); + struct tree_node *n; + REFTABLE_CALLOC_ARRAY(n, 1); n->key = key; *rootp = n; return *rootp; diff --git a/reftable/tree_test.c b/reftable/tree_test.c index ac3a045ad4..6961a657ad 100644 --- a/reftable/tree_test.c +++ b/reftable/tree_test.c @@ -9,8 +9,6 @@ https://developers.google.com/open-source/licenses/bsd #include "system.h" #include "tree.h" -#include "basics.h" -#include "record.h" #include "test_framework.h" #include "reftable-tests.h" diff --git a/reftable/writer.c b/reftable/writer.c index 2e322a5683..1d9ff0fbfa 100644 --- a/reftable/writer.c +++ b/reftable/writer.c @@ -49,7 +49,7 @@ static int padded_write(struct reftable_writer *w, uint8_t *data, size_t len, { int n = 0; if (w->pending_padding > 0) { - uint8_t *zeroed = reftable_calloc(w->pending_padding); + uint8_t *zeroed = reftable_calloc(w->pending_padding, sizeof(*zeroed)); int n = w->write(w->write_arg, zeroed, w->pending_padding); if (n < 0) return n; @@ -121,10 +121,10 @@ static struct strbuf reftable_empty_strbuf = STRBUF_INIT; struct reftable_writer * reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t), + int (*flush_func)(void *), void *writer_arg, struct reftable_write_options *opts) { - struct reftable_writer *wp = - reftable_calloc(sizeof(struct reftable_writer)); + struct reftable_writer *wp = reftable_calloc(1, sizeof(*wp)); strbuf_init(&wp->block_writer_data.last_key, 0); options_set_defaults(opts); if (opts->block_size >= (1 << 24)) { @@ -132,10 +132,11 @@ reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t), abort(); } wp->last_key = reftable_empty_strbuf; - wp->block = reftable_calloc(opts->block_size); + REFTABLE_CALLOC_ARRAY(wp->block, opts->block_size); wp->write = writer_func; wp->write_arg = writer_arg; wp->opts = *opts; + wp->flush = flush_func; writer_reinit_block_writer(wp, BLOCK_TYPE_REF); return wp; @@ -200,12 +201,7 @@ static void writer_index_hash(struct reftable_writer *w, struct strbuf *hash) return; } - if (key->offset_len == key->offset_cap) { - key->offset_cap = 2 * key->offset_cap + 1; - key->offsets = reftable_realloc( - key->offsets, sizeof(uint64_t) * key->offset_cap); - } - + REFTABLE_ALLOC_GROW(key->offsets, key->offset_len + 1, key->offset_cap); key->offsets[key->offset_len++] = off; } @@ -377,20 +373,39 @@ int reftable_writer_add_logs(struct reftable_writer *w, static int writer_finish_section(struct reftable_writer *w) { + struct reftable_block_stats *bstats = NULL; uint8_t typ = block_writer_type(w->block_writer); uint64_t index_start = 0; int max_level = 0; - int threshold = w->opts.unpadded ? 1 : 3; + size_t threshold = w->opts.unpadded ? 1 : 3; int before_blocks = w->stats.idx_stats.blocks; - int err = writer_flush_block(w); - int i = 0; - struct reftable_block_stats *bstats = NULL; + int err; + + err = writer_flush_block(w); if (err < 0) return err; + /* + * When the section we are about to index has a lot of blocks then the + * index itself may span across multiple blocks, as well. This would + * require a linear scan over index blocks only to find the desired + * indexed block, which is inefficient. Instead, we write a multi-level + * index where index records of level N+1 will refer to index blocks of + * level N. This isn't constant time, either, but at least logarithmic. + * + * This loop handles writing this multi-level index. Note that we write + * the lowest-level index pointing to the indexed blocks first. We then + * continue writing additional index levels until the current level has + * less blocks than the threshold so that the highest level will be at + * the end of the index section. + * + * Readers are thus required to start reading the index section from + * its end, which is why we set `index_start` to the beginning of the + * last index section. + */ while (w->index_len > threshold) { struct reftable_index_record *idx = NULL; - int idx_len = 0; + size_t i, idx_len; max_level++; index_start = w->next; @@ -409,35 +424,28 @@ static int writer_finish_section(struct reftable_writer *w) .idx = idx[i], }, }; - if (block_writer_add(w->block_writer, &rec) == 0) { - continue; - } - err = writer_flush_block(w); + err = writer_add_record(w, &rec); if (err < 0) return err; + } - writer_reinit_block_writer(w, BLOCK_TYPE_INDEX); + err = writer_flush_block(w); + if (err < 0) + return err; - err = block_writer_add(w->block_writer, &rec); - if (err != 0) { - /* write into fresh block should always succeed - */ - abort(); - } - } - for (i = 0; i < idx_len; i++) { + for (i = 0; i < idx_len; i++) strbuf_release(&idx[i].last_key); - } reftable_free(idx); } + /* + * The index may still contain a number of index blocks lower than the + * threshold. Clear it so that these entries don't leak into the next + * index section. + */ writer_clear_index(w); - err = writer_flush_block(w); - if (err < 0) - return err; - bstats = writer_reftable_block_stats(w, typ); bstats->index_blocks = w->stats.idx_stats.blocks - before_blocks; bstats->index_offset = index_start; @@ -603,6 +611,12 @@ int reftable_writer_close(struct reftable_writer *w) put_be32(p, crc32(0, footer, p - footer)); p += 4; + err = w->flush(w->write_arg); + if (err < 0) { + err = REFTABLE_IO_ERROR; + goto done; + } + err = padded_write(w, footer, footer_size(writer_version(w)), 0); if (err < 0) goto done; @@ -622,11 +636,8 @@ done: static void writer_clear_index(struct reftable_writer *w) { - int i = 0; - for (i = 0; i < w->index_len; i++) { + for (size_t i = 0; i < w->index_len; i++) strbuf_release(&w->index[i].last_key); - } - FREE_AND_NULL(w->index); w->index_len = 0; w->index_cap = 0; @@ -674,12 +685,7 @@ static int writer_flush_nonempty_block(struct reftable_writer *w) if (err < 0) return err; - if (w->index_cap == w->index_len) { - w->index_cap = 2 * w->index_cap + 1; - w->index = reftable_realloc( - w->index, - sizeof(struct reftable_index_record) * w->index_cap); - } + REFTABLE_ALLOC_GROW(w->index, w->index_len + 1, w->index_cap); ir.offset = w->next; strbuf_reset(&ir.last_key); diff --git a/reftable/writer.h b/reftable/writer.h index 09b88673d9..8d0df9cc52 100644 --- a/reftable/writer.h +++ b/reftable/writer.h @@ -16,6 +16,7 @@ https://developers.google.com/open-source/licenses/bsd struct reftable_writer { ssize_t (*write)(void *, const void *, size_t); + int (*flush)(void *); void *write_arg; int pending_padding; struct strbuf last_key; diff --git a/remote-curl.c b/remote-curl.c index ef05752ca5..1161dc7fed 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -8,11 +8,9 @@ #include "strbuf.h" #include "walker.h" #include "http.h" -#include "exec-cmd.h" #include "run-command.h" #include "pkt-line.h" #include "string-list.h" -#include "sideband.h" #include "strvec.h" #include "credential.h" #include "oid-array.h" @@ -22,6 +20,7 @@ #include "quote.h" #include "trace2.h" #include "transport.h" +#include "url.h" #include "write-or-die.h" static struct remote *remote; @@ -1447,8 +1446,14 @@ static int stateless_connect(const char *service_name) * establish a stateless connection, otherwise we need to tell the * client to fallback to using other transport helper functions to * complete their request. + * + * The "git-upload-archive" service is a read-only operation. Fallback + * to use "git-upload-pack" service to discover protocol version. */ - discover = discover_refs(service_name, 0); + if (!strcmp(service_name, "git-upload-archive")) + discover = discover_refs("git-upload-pack", 0); + else + discover = discover_refs(service_name, 0); if (discover->version != protocol_v2) { printf("fallback\n"); fflush(stdout); @@ -1486,9 +1491,11 @@ static int stateless_connect(const char *service_name) /* * Dump the capability listing that we got from the server earlier - * during the info/refs request. + * during the info/refs request. This does not work with the + * "git-upload-archive" service. */ - write_or_die(rpc.in, discover->buf, discover->len); + if (strcmp(service_name, "git-upload-archive")) + write_or_die(rpc.in, discover->buf, discover->len); /* Until we see EOF keep sending POSTs */ while (1) { @@ -1564,8 +1571,11 @@ int cmd_main(int argc, const char **argv) if (buf.len == 0) break; if (starts_with(buf.buf, "fetch ")) { - if (nongit) - die(_("remote-curl: fetch attempted without a local repo")); + if (nongit) { + setup_git_directory_gently(&nongit); + if (nongit) + die(_("remote-curl: fetch attempted without a local repo")); + } parse_fetch(&buf); } else if (!strcmp(buf.buf, "list") || starts_with(buf.buf, "list ")) { @@ -15,7 +15,6 @@ #include "diff.h" #include "revision.h" #include "dir.h" -#include "tag.h" #include "setup.h" #include "string-list.h" #include "strvec.h" @@ -106,7 +105,7 @@ static int remotes_hash_cmp(const void *cmp_data UNUSED, b = container_of(entry_or_key, const struct remote, ent); if (key) - return strncmp(a->name, key->str, key->len) || a->name[key->len]; + return !!xstrncmpz(a->name, key->str, key->len); else return strcmp(a->name, b->name); } @@ -190,8 +189,7 @@ static int branches_hash_cmp(const void *cmp_data UNUSED, b = container_of(entry_or_key, const struct branch, ent); if (key) - return strncmp(a->name, key->str, key->len) || - a->name[key->len]; + return !!xstrncmpz(a->name, key->str, key->len); else return strcmp(a->name, b->name); } @@ -509,7 +507,7 @@ static void alias_all_urls(struct remote_state *remote_state) } } -static void read_config(struct repository *repo) +static void read_config(struct repository *repo, int early) { int flag; @@ -518,7 +516,7 @@ static void read_config(struct repository *repo) repo->remote_state->initialized = 1; repo->remote_state->current_branch = NULL; - if (startup_info->have_repository) { + if (startup_info->have_repository && !early) { const char *head_ref = refs_resolve_ref_unsafe( get_main_ref_store(repo), "HEAD", 0, NULL, &flag); if (head_ref && (flag & REF_ISSYMREF) && @@ -561,7 +559,7 @@ static const char *remotes_remote_for_branch(struct remote_state *remote_state, const char *remote_for_branch(struct branch *branch, int *explicit) { - read_config(the_repository); + read_config(the_repository, 0); die_on_missing_branch(the_repository, branch); return remotes_remote_for_branch(the_repository->remote_state, branch, @@ -587,7 +585,7 @@ remotes_pushremote_for_branch(struct remote_state *remote_state, const char *pushremote_for_branch(struct branch *branch, int *explicit) { - read_config(the_repository); + read_config(the_repository, 0); die_on_missing_branch(the_repository, branch); return remotes_pushremote_for_branch(the_repository->remote_state, @@ -599,7 +597,7 @@ static struct remote *remotes_remote_get(struct remote_state *remote_state, const char *remote_ref_for_branch(struct branch *branch, int for_push) { - read_config(the_repository); + read_config(the_repository, 0); die_on_missing_branch(the_repository, branch); if (branch) { @@ -709,7 +707,13 @@ remotes_remote_get(struct remote_state *remote_state, const char *name) struct remote *remote_get(const char *name) { - read_config(the_repository); + read_config(the_repository, 0); + return remotes_remote_get(the_repository->remote_state, name); +} + +struct remote *remote_get_early(const char *name) +{ + read_config(the_repository, 1); return remotes_remote_get(the_repository->remote_state, name); } @@ -722,7 +726,7 @@ remotes_pushremote_get(struct remote_state *remote_state, const char *name) struct remote *pushremote_get(const char *name) { - read_config(the_repository); + read_config(the_repository, 0); return remotes_pushremote_get(the_repository->remote_state, name); } @@ -738,7 +742,7 @@ int remote_is_configured(struct remote *remote, int in_repo) int for_each_remote(each_remote_fn fn, void *priv) { int i, result = 0; - read_config(the_repository); + read_config(the_repository, 0); for (i = 0; i < the_repository->remote_state->remotes_nr && !result; i++) { struct remote *remote = @@ -1831,7 +1835,7 @@ struct branch *branch_get(const char *name) { struct branch *ret; - read_config(the_repository); + read_config(the_repository, 0); if (!name || !*name || !strcmp(name, "HEAD")) ret = the_repository->remote_state->current_branch; else @@ -1973,7 +1977,7 @@ static const char *branch_get_push_1(struct remote_state *remote_state, const char *branch_get_push(struct branch *branch, struct strbuf *err) { - read_config(the_repository); + read_config(the_repository, 0); die_on_missing_branch(the_repository, branch); if (!branch) @@ -118,6 +118,7 @@ struct remote { * and configuration. */ struct remote *remote_get(const char *name); +struct remote *remote_get_early(const char *name); struct remote *pushremote_get(const char *name); int remote_is_configured(struct remote *remote, int in_repo); @@ -400,8 +401,6 @@ struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map); /* * Compare-and-swap */ -#define CAS_OPT_NAME "force-with-lease" - struct push_cas_option { unsigned use_tracking_for_rest:1; unsigned use_force_if_includes:1; diff --git a/repo-settings.c b/repo-settings.c index 525f69c0c7..a0b590bc6c 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -2,7 +2,6 @@ #include "config.h" #include "repository.h" #include "midx.h" -#include "compat/fsmonitor/fsm-listen.h" static void repo_cfg_bool(struct repository *r, const char *key, int *dest, int def) @@ -44,6 +43,7 @@ void prepare_repo_settings(struct repository *r) if (experimental) { r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING; r->settings.pack_use_bitmap_boundary_traversal = 1; + r->settings.pack_use_multi_pack_reuse = 1; } if (manyfiles) { r->settings.index_version = 4; diff --git a/repository.c b/repository.c index a7679ceeaa..7aacb51b65 100644 --- a/repository.c +++ b/repository.c @@ -104,6 +104,11 @@ void repo_set_hash_algo(struct repository *repo, int hash_algo) repo->hash_algo = &hash_algos[hash_algo]; } +void repo_set_ref_storage_format(struct repository *repo, unsigned int format) +{ + repo->ref_storage_format = format; +} + /* * Attempt to resolve and set the provided 'gitdir' for repository 'repo'. * Return 0 upon success and a non-zero value upon failure. @@ -184,6 +189,7 @@ int repo_init(struct repository *repo, goto error; repo_set_hash_algo(repo, format.hash_algo); + repo_set_ref_storage_format(repo, format.ref_storage_format); repo->repository_format_worktree_config = format.worktree_config; /* take ownership of format.partial_clone */ @@ -256,8 +262,6 @@ static void repo_clear_path_cache(struct repo_path_cache *cache) FREE_AND_NULL(cache->merge_rr); FREE_AND_NULL(cache->merge_mode); FREE_AND_NULL(cache->merge_head); - FREE_AND_NULL(cache->merge_autostash); - FREE_AND_NULL(cache->auto_merge); FREE_AND_NULL(cache->fetch_head); FREE_AND_NULL(cache->shallow); } diff --git a/repository.h b/repository.h index 5f18486f64..9bf1e33d25 100644 --- a/repository.h +++ b/repository.h @@ -24,6 +24,10 @@ enum fetch_negotiation_setting { FETCH_NEGOTIATION_NOOP, }; +#define REF_STORAGE_FORMAT_UNKNOWN 0 +#define REF_STORAGE_FORMAT_FILES 1 +#define REF_STORAGE_FORMAT_REFTABLE 2 + struct repo_settings { int initialized; @@ -36,6 +40,7 @@ struct repo_settings { int sparse_index; int pack_read_reverse_index; int pack_use_bitmap_boundary_traversal; + int pack_use_multi_pack_reuse; /* * Does this repository have core.useReplaceRefs=true (on by @@ -64,8 +69,6 @@ struct repo_path_cache { char *merge_rr; char *merge_mode; char *merge_head; - char *merge_autostash; - char *auto_merge; char *fetch_head; char *shallow; }; @@ -160,6 +163,9 @@ struct repository { /* Repository's current hash algorithm, as serialized on disk. */ const struct git_hash_algo *hash_algo; + /* Repository's reference storage format, as serialized on disk. */ + unsigned int ref_storage_format; + /* A unique-id for tracing purposes. */ int trace2_repo_id; @@ -199,6 +205,7 @@ void repo_set_gitdir(struct repository *repo, const char *root, const struct set_gitdir_args *extra_args); void repo_set_worktree(struct repository *repo, const char *path); void repo_set_hash_algo(struct repository *repo, int algo); +void repo_set_ref_storage_format(struct repository *repo, unsigned int format); void initialize_the_repository(void); RESULT_MUST_BE_USED int repo_init(struct repository *r, const char *gitdir, const char *worktree); @@ -12,12 +12,10 @@ #include "dir.h" #include "resolve-undo.h" #include "merge-ll.h" -#include "attr.h" #include "path.h" #include "pathspec.h" #include "object-file.h" #include "object-store-ll.h" -#include "hash-lookup.h" #include "strmap.h" #define RESOLVED 0 @@ -975,6 +973,9 @@ static int handle_cache(struct index_state *istate, mmfile[i].ptr = repo_read_object_file(the_repository, &ce->oid, &type, &size); + if (!mmfile[i].ptr) + die(_("unable to read %s"), + oid_to_hex(&ce->oid)); mmfile[i].size = size; } } @@ -6,7 +6,6 @@ #include "object-name.h" #include "refs.h" #include "reset.h" -#include "run-command.h" #include "tree-walk.h" #include "tree.h" #include "unpack-trees.h" diff --git a/revision.c b/revision.c index 00d5c29bfc..ac45c6d8f2 100644 --- a/revision.c +++ b/revision.c @@ -21,12 +21,10 @@ #include "reflog-walk.h" #include "patch-ids.h" #include "decorate.h" -#include "log-tree.h" #include "string-list.h" #include "line-log.h" #include "mailmap.h" #include "commit-slab.h" -#include "dir.h" #include "cache-tree.h" #include "bisect.h" #include "packfile.h" @@ -1688,9 +1686,7 @@ static int handle_one_reflog_ent(struct object_id *ooid, struct object_id *noid, return 0; } -static int handle_one_reflog(const char *refname_in_wt, - const struct object_id *oid UNUSED, - int flag UNUSED, void *cb_data) +static int handle_one_reflog(const char *refname_in_wt, void *cb_data) { struct all_refs_cb *cb = cb_data; struct strbuf refname = STRBUF_INIT; @@ -2223,6 +2219,27 @@ static void add_message_grep(struct rev_info *revs, const char *pattern) add_grep(revs, pattern, GREP_PATTERN_BODY); } +static int parse_count(const char *arg) +{ + int count; + + if (strtol_i(arg, 10, &count) < 0) + die("'%s': not an integer", arg); + return count; +} + +static timestamp_t parse_age(const char *arg) +{ + timestamp_t num; + char *p; + + errno = 0; + num = parse_timestamp(arg, &p, 10); + if (errno || *p || p == arg) + die("'%s': not a number of seconds since epoch", arg); + return num; +} + static int handle_revision_opt(struct rev_info *revs, int argc, const char **argv, int *unkc, const char **unkv, const struct setup_revision_opt* opt) @@ -2249,29 +2266,27 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } if ((argcount = parse_long_opt("max-count", argv, &optarg))) { - revs->max_count = atoi(optarg); + revs->max_count = parse_count(optarg); revs->no_walk = 0; return argcount; } else if ((argcount = parse_long_opt("skip", argv, &optarg))) { - revs->skip_count = atoi(optarg); + revs->skip_count = parse_count(optarg); return argcount; } else if ((*arg == '-') && isdigit(arg[1])) { /* accept -<digit>, like traditional "head" */ - if (strtol_i(arg + 1, 10, &revs->max_count) < 0 || - revs->max_count < 0) - die("'%s': not a non-negative integer", arg + 1); + revs->max_count = parse_count(arg + 1); revs->no_walk = 0; } else if (!strcmp(arg, "-n")) { if (argc <= 1) return error("-n requires an argument"); - revs->max_count = atoi(argv[1]); + revs->max_count = parse_count(argv[1]); revs->no_walk = 0; return 2; } else if (skip_prefix(arg, "-n", &optarg)) { - revs->max_count = atoi(optarg); + revs->max_count = parse_count(optarg); revs->no_walk = 0; } else if ((argcount = parse_long_opt("max-age", argv, &optarg))) { - revs->max_age = atoi(optarg); + revs->max_age = parse_age(optarg); return argcount; } else if ((argcount = parse_long_opt("since", argv, &optarg))) { revs->max_age = approxidate(optarg); @@ -2283,7 +2298,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->max_age = approxidate(optarg); return argcount; } else if ((argcount = parse_long_opt("min-age", argv, &optarg))) { - revs->min_age = atoi(optarg); + revs->min_age = parse_age(optarg); return argcount; } else if ((argcount = parse_long_opt("before", argv, &optarg))) { revs->min_age = approxidate(optarg); @@ -2371,11 +2386,11 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--no-merges")) { revs->max_parents = 1; } else if (skip_prefix(arg, "--min-parents=", &optarg)) { - revs->min_parents = atoi(optarg); + revs->min_parents = parse_count(optarg); } else if (!strcmp(arg, "--no-min-parents")) { revs->min_parents = 0; } else if (skip_prefix(arg, "--max-parents=", &optarg)) { - revs->max_parents = atoi(optarg); + revs->max_parents = parse_count(optarg); } else if (!strcmp(arg, "--no-max-parents")) { revs->max_parents = -1; } else if (!strcmp(arg, "--boundary")) { @@ -2384,8 +2399,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->left_right = 1; } else if (!strcmp(arg, "--left-only")) { if (revs->right_only) - die("--left-only is incompatible with --right-only" - " or --cherry"); + die(_("options '%s' and '%s' cannot be used together"), + "--left-only", "--right-only/--cherry"); revs->left_only = 1; } else if (!strcmp(arg, "--right-only")) { if (revs->left_only) @@ -2709,7 +2724,8 @@ static int handle_revision_pseudo_opt(struct rev_info *revs, clear_ref_exclusions(&revs->ref_excludes); } else if (!strcmp(arg, "--branches")) { if (revs->ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --branches")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--branches"); handle_refs(refs, revs, *flags, refs_for_each_branch_ref); clear_ref_exclusions(&revs->ref_excludes); } else if (!strcmp(arg, "--bisect")) { @@ -2720,12 +2736,14 @@ static int handle_revision_pseudo_opt(struct rev_info *revs, revs->bisect = 1; } else if (!strcmp(arg, "--tags")) { if (revs->ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --tags")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--tags"); handle_refs(refs, revs, *flags, refs_for_each_tag_ref); clear_ref_exclusions(&revs->ref_excludes); } else if (!strcmp(arg, "--remotes")) { if (revs->ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --remotes")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--remotes"); handle_refs(refs, revs, *flags, refs_for_each_remote_ref); clear_ref_exclusions(&revs->ref_excludes); } else if ((argcount = parse_long_opt("glob", argv, &optarg))) { @@ -2743,21 +2761,24 @@ static int handle_revision_pseudo_opt(struct rev_info *revs, } else if (skip_prefix(arg, "--branches=", &optarg)) { struct all_refs_cb cb; if (revs->ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --branches")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--branches"); init_all_refs_cb(&cb, revs, *flags); for_each_glob_ref_in(handle_one_ref, optarg, "refs/heads/", &cb); clear_ref_exclusions(&revs->ref_excludes); } else if (skip_prefix(arg, "--tags=", &optarg)) { struct all_refs_cb cb; if (revs->ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --tags")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--tags"); init_all_refs_cb(&cb, revs, *flags); for_each_glob_ref_in(handle_one_ref, optarg, "refs/tags/", &cb); clear_ref_exclusions(&revs->ref_excludes); } else if (skip_prefix(arg, "--remotes=", &optarg)) { struct all_refs_cb cb; if (revs->ref_excludes.hidden_refs_configured) - return error(_("--exclude-hidden cannot be used together with --remotes")); + return error(_("options '%s' and '%s' cannot be used together"), + "--exclude-hidden", "--remotes"); init_all_refs_cb(&cb, revs, *flags); for_each_glob_ref_in(handle_one_ref, optarg, "refs/remotes/", &cb); clear_ref_exclusions(&revs->ref_excludes); @@ -3036,8 +3057,6 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s revs->grep_filter.ignore_locale = 1; compile_grep_patterns(&revs->grep_filter); - if (revs->reverse && revs->reflog_info) - die(_("options '%s' and '%s' cannot be used together"), "--reverse", "--walk-reflogs"); if (revs->reflog_info && revs->limited) die("cannot combine --walk-reflogs with history-limiting options"); if (revs->rewrite_parents && revs->children.name) @@ -3048,11 +3067,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s /* * Limitations on the graph functionality */ - if (revs->reverse && revs->graph) - die(_("options '%s' and '%s' cannot be used together"), "--reverse", "--graph"); + die_for_incompatible_opt3(!!revs->graph, "--graph", + !!revs->reverse, "--reverse", + !!revs->reflog_info, "--walk-reflogs"); - if (revs->reflog_info && revs->graph) - die(_("options '%s' and '%s' cannot be used together"), "--walk-reflogs", "--graph"); if (revs->no_walk && revs->graph) die(_("options '%s' and '%s' cannot be used together"), "--no-walk", "--graph"); if (!revs->reflog_info && revs->grep_filter.use_reflog_filter) diff --git a/run-command.c b/run-command.c index a558042c87..0e7435718a 100644 --- a/run-command.c +++ b/run-command.c @@ -14,9 +14,7 @@ #include "quote.h" #include "config.h" #include "packfile.h" -#include "hook.h" #include "compat/nonblock.h" -#include "alloc.h" void child_process_init(struct child_process *child) { diff --git a/send-pack.c b/send-pack.c index 89aca9d829..37f59d4f66 100644 --- a/send-pack.c +++ b/send-pack.c @@ -4,7 +4,6 @@ #include "date.h" #include "gettext.h" #include "hex.h" -#include "refs.h" #include "object-store-ll.h" #include "pkt-line.h" #include "sideband.h" @@ -12,7 +11,6 @@ #include "remote.h" #include "connect.h" #include "send-pack.h" -#include "quote.h" #include "transport.h" #include "version.h" #include "oid-array.h" diff --git a/sequencer.c b/sequencer.c index d584cac8ed..f49a871ac0 100644 --- a/sequencer.c +++ b/sequencer.c @@ -15,10 +15,8 @@ #include "pager.h" #include "commit.h" #include "sequencer.h" -#include "tag.h" #include "run-command.h" #include "hook.h" -#include "exec-cmd.h" #include "utf8.h" #include "cache-tree.h" #include "diff.h" @@ -39,7 +37,6 @@ #include "notes-utils.h" #include "sigchain.h" #include "unpack-trees.h" -#include "worktree.h" #include "oidmap.h" #include "oidset.h" #include "commit-slab.h" @@ -238,34 +235,29 @@ static int git_sequencer_config(const char *k, const char *v, const struct config_context *ctx, void *cb) { struct replay_opts *opts = cb; - int status; if (!strcmp(k, "commit.cleanup")) { - const char *s; + if (!v) + return config_error_nonbool(k); - status = git_config_string(&s, k, v); - if (status) - return status; - - if (!strcmp(s, "verbatim")) { + if (!strcmp(v, "verbatim")) { opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_NONE; opts->explicit_cleanup = 1; - } else if (!strcmp(s, "whitespace")) { + } else if (!strcmp(v, "whitespace")) { opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_SPACE; opts->explicit_cleanup = 1; - } else if (!strcmp(s, "strip")) { + } else if (!strcmp(v, "strip")) { opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_ALL; opts->explicit_cleanup = 1; - } else if (!strcmp(s, "scissors")) { + } else if (!strcmp(v, "scissors")) { opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_SCISSORS; opts->explicit_cleanup = 1; } else { warning(_("invalid commit message cleanup mode '%s'"), - s); + v); } - free((char *)s); - return status; + return 0; } if (!strcmp(k, "commit.gpgsign")) { @@ -345,7 +337,7 @@ static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob, if (ignore_footer) sb->buf[sb->len - ignore_footer] = saved_char; - if (info.trailer_start == info.trailer_end) + if (info.trailer_block_start == info.trailer_block_end) return 0; for (i = 0; i < info.trailer_nr; i++) @@ -482,7 +474,7 @@ static void print_advice(struct repository *r, int show_hint, * of the commit itself so remove CHERRY_PICK_HEAD */ refs_delete_ref(get_main_ref_store(r), "", "CHERRY_PICK_HEAD", - NULL, 0); + NULL, REF_NO_DEREF); return; } @@ -1675,7 +1667,7 @@ static int do_commit(struct repository *r, strbuf_release(&sb); if (!res) { refs_delete_ref(get_main_ref_store(r), "", - "CHERRY_PICK_HEAD", NULL, 0); + "CHERRY_PICK_HEAD", NULL, REF_NO_DEREF); unlink(git_path_merge_msg(r)); if (!is_rebase_i(opts)) print_commit_summary(r, NULL, &oid, @@ -2414,9 +2406,10 @@ static int do_pick_commit(struct repository *r, } else if (allow == 2) { drop_commit = 1; refs_delete_ref(get_main_ref_store(r), "", "CHERRY_PICK_HEAD", - NULL, 0); + NULL, REF_NO_DEREF); unlink(git_path_merge_msg(r)); - unlink(git_path_auto_merge(r)); + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE", + NULL, REF_NO_DEREF); fprintf(stderr, _("dropping %s %s -- patch contents already upstream\n"), oid_to_hex(&commit->object.oid), msg.subject); @@ -2810,7 +2803,7 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose) if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD")) { if (!refs_delete_ref(get_main_ref_store(r), "", - "CHERRY_PICK_HEAD", NULL, 0) && + "CHERRY_PICK_HEAD", NULL, REF_NO_DEREF) && verbose) warning(_("cancelling a cherry picking in progress")); opts.action = REPLAY_PICK; @@ -2819,14 +2812,15 @@ void sequencer_post_commit_cleanup(struct repository *r, int verbose) if (refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) { if (!refs_delete_ref(get_main_ref_store(r), "", "REVERT_HEAD", - NULL, 0) && + NULL, REF_NO_DEREF) && verbose) warning(_("cancelling a revert in progress")); opts.action = REPLAY_REVERT; need_cleanup = 1; } - unlink(git_path_auto_merge(r)); + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE", + NULL, REF_NO_DEREF); if (!need_cleanup) return; @@ -3647,6 +3641,7 @@ static int do_exec(struct repository *r, const char *command_line) fprintf(stderr, _("Executing: %s\n"), command_line); cmd.use_shell = 1; strvec_push(&cmd.args, command_line); + strvec_push(&cmd.env, "GIT_CHERRY_PICK_HELP"); status = run_command(&cmd); /* force re-reading of the cache */ @@ -4124,7 +4119,7 @@ static int do_merge(struct repository *r, strbuf_release(&ref_name); refs_delete_ref(get_main_ref_store(r), "", "CHERRY_PICK_HEAD", - NULL, 0); + NULL, REF_NO_DEREF); rollback_lock_file(&lock); ret = run_command(&cmd); @@ -4469,12 +4464,17 @@ static enum todo_command peek_command(struct todo_list *todo_list, int offset) return -1; } -void create_autostash(struct repository *r, const char *path) +static void create_autostash_internal(struct repository *r, + const char *path, + const char *refname) { struct strbuf buf = STRBUF_INIT; struct lock_file lock_file = LOCK_INIT; int fd; + if (path && refname) + BUG("can only pass path or refname"); + fd = repo_hold_locked_index(r, &lock_file, 0); refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL); if (0 <= fd) @@ -4501,10 +4501,16 @@ void create_autostash(struct repository *r, const char *path) strbuf_reset(&buf); strbuf_add_unique_abbrev(&buf, &oid, DEFAULT_ABBREV); - if (safe_create_leading_directories_const(path)) - die(_("Could not create directory for '%s'"), - path); - write_file(path, "%s", oid_to_hex(&oid)); + if (path) { + if (safe_create_leading_directories_const(path)) + die(_("Could not create directory for '%s'"), + path); + write_file(path, "%s", oid_to_hex(&oid)); + } else { + refs_update_ref(get_main_ref_store(r), "", refname, + &oid, null_oid(), 0, UPDATE_REFS_DIE_ON_ERR); + } + printf(_("Created autostash: %s\n"), buf.buf); if (reset_head(r, &ropts) < 0) die(_("could not reset --hard")); @@ -4515,6 +4521,16 @@ void create_autostash(struct repository *r, const char *path) strbuf_release(&buf); } +void create_autostash(struct repository *r, const char *path) +{ + create_autostash_internal(r, path, NULL); +} + +void create_autostash_ref(struct repository *r, const char *refname) +{ + create_autostash_internal(r, NULL, refname); +} + static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply) { struct child_process child = CHILD_PROCESS_INIT; @@ -4592,6 +4608,41 @@ int apply_autostash_oid(const char *stash_oid) return apply_save_autostash_oid(stash_oid, 1); } +static int apply_save_autostash_ref(struct repository *r, const char *refname, + int attempt_apply) +{ + struct object_id stash_oid; + char stash_oid_hex[GIT_MAX_HEXSZ + 1]; + int flag, ret; + + if (!refs_ref_exists(get_main_ref_store(r), refname)) + return 0; + + if (!refs_resolve_ref_unsafe(get_main_ref_store(r), refname, + RESOLVE_REF_READING, &stash_oid, &flag)) + return -1; + if (flag & REF_ISSYMREF) + return error(_("autostash reference is a symref")); + + oid_to_hex_r(stash_oid_hex, &stash_oid); + ret = apply_save_autostash_oid(stash_oid_hex, attempt_apply); + + refs_delete_ref(get_main_ref_store(r), "", refname, + &stash_oid, REF_NO_DEREF); + + return ret; +} + +int save_autostash_ref(struct repository *r, const char *refname) +{ + return apply_save_autostash_ref(r, refname, 0); +} + +int apply_autostash_ref(struct repository *r, const char *refname) +{ + return apply_save_autostash_ref(r, refname, 1); +} + static int checkout_onto(struct repository *r, struct replay_opts *opts, const char *onto_name, const struct object_id *onto, const struct object_id *orig_head) @@ -4774,8 +4825,10 @@ static int pick_commits(struct repository *r, } unlink(rebase_path_author_script()); unlink(git_path_merge_head(r)); - unlink(git_path_auto_merge(r)); - delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF); + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE", + NULL, REF_NO_DEREF); + refs_delete_ref(get_main_ref_store(r), "", "REBASE_HEAD", + NULL, REF_NO_DEREF); if (item->command == TODO_BREAK) { if (!opts->verbose) @@ -5116,7 +5169,7 @@ static int commit_staged_changes(struct repository *r, if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") && refs_delete_ref(get_main_ref_store(r), "", - "CHERRY_PICK_HEAD", NULL, 0)) + "CHERRY_PICK_HEAD", NULL, REF_NO_DEREF)) return error(_("could not remove CHERRY_PICK_HEAD")); if (unlink(git_path_merge_msg(r)) && errno != ENOENT) return error_errno(_("could not remove '%s'"), @@ -5130,7 +5183,8 @@ static int commit_staged_changes(struct repository *r, return error(_("could not commit staged changes.")); unlink(rebase_path_amend()); unlink(git_path_merge_head(r)); - unlink(git_path_auto_merge(r)); + refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE", + NULL, REF_NO_DEREF); if (final_fixup) { unlink(rebase_path_fixup_msg()); unlink(rebase_path_squash_msg()); diff --git a/sequencer.h b/sequencer.h index 913a0f652d..dcef7bb99c 100644 --- a/sequencer.h +++ b/sequencer.h @@ -225,9 +225,12 @@ void commit_post_rewrite(struct repository *r, const struct object_id *new_head); void create_autostash(struct repository *r, const char *path); +void create_autostash_ref(struct repository *r, const char *refname); int save_autostash(const char *path); +int save_autostash_ref(struct repository *r, const char *refname); int apply_autostash(const char *path); int apply_autostash_oid(const char *stash_oid); +int apply_autostash_ref(struct repository *r, const char *refname); #define SUMMARY_INITIAL_COMMIT (1 << 0) #define SUMMARY_SHOW_AUTHOR_DATE (1 << 1) @@ -13,7 +13,6 @@ #include "string-list.h" #include "chdir-notify.h" #include "path.h" -#include "promisor-remote.h" #include "quote.h" #include "trace2.h" #include "worktree.h" @@ -559,6 +558,8 @@ static enum extension_result handle_extension_v0(const char *var, data->precious_objects = git_config_bool(var, value); return EXTENSION_OK; } else if (!strcmp(ext, "partialclone")) { + if (!value) + return config_error_nonbool(var); data->partial_clone = xstrdup(value); return EXTENSION_OK; } else if (!strcmp(ext, "worktreeconfig")) { @@ -590,6 +591,17 @@ static enum extension_result handle_extension(const char *var, "extensions.objectformat", value); data->hash_algo = format; return EXTENSION_OK; + } else if (!strcmp(ext, "refstorage")) { + unsigned int format; + + if (!value) + return config_error_nonbool(var); + format = ref_storage_format_by_name(value); + if (format == REF_STORAGE_FORMAT_UNKNOWN) + return error(_("invalid value for '%s': '%s'"), + "extensions.refstorage", value); + data->ref_storage_format = format; + return EXTENSION_OK; } return EXTENSION_UNKNOWN; } @@ -1359,7 +1371,8 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, if (is_git_directory(dir->buf)) { trace2_data_string("setup", NULL, "implicit-bare-repository", dir->buf); - if (get_allowed_bare_repo() == ALLOWED_BARE_REPO_EXPLICIT) + if (get_allowed_bare_repo() == ALLOWED_BARE_REPO_EXPLICIT && + !ends_with_path_components(dir->buf, ".git")) return GIT_DIR_DISALLOWED_BARE; if (!ensure_valid_ownership(NULL, NULL, dir->buf, report)) return GIT_DIR_INVALID_OWNERSHIP; @@ -1564,6 +1577,8 @@ const char *setup_git_directory_gently(int *nongit_ok) } if (startup_info->have_repository) { repo_set_hash_algo(the_repository, repo_fmt.hash_algo); + repo_set_ref_storage_format(the_repository, + repo_fmt.ref_storage_format); the_repository->repository_format_worktree_config = repo_fmt.worktree_config; /* take ownership of repo_fmt.partial_clone */ @@ -1657,6 +1672,8 @@ void check_repository_format(struct repository_format *fmt) check_repository_format_gently(get_git_dir(), fmt, NULL); startup_info->have_repository = 1; repo_set_hash_algo(the_repository, fmt->hash_algo); + repo_set_ref_storage_format(the_repository, + fmt->ref_storage_format); the_repository->repository_format_worktree_config = fmt->worktree_config; the_repository->repository_format_partial_clone = @@ -1865,12 +1882,15 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree) return 1; } -void initialize_repository_version(int hash_algo, int reinit) +void initialize_repository_version(int hash_algo, + unsigned int ref_storage_format, + int reinit) { char repo_version_string[10]; int repo_version = GIT_REPO_VERSION; - if (hash_algo != GIT_HASH_SHA1) + if (hash_algo != GIT_HASH_SHA1 || + ref_storage_format != REF_STORAGE_FORMAT_FILES) repo_version = GIT_REPO_VERSION_READ; /* This forces creation of new config file */ @@ -1883,23 +1903,72 @@ void initialize_repository_version(int hash_algo, int reinit) hash_algos[hash_algo].name); else if (reinit) git_config_set_gently("extensions.objectformat", NULL); + + if (ref_storage_format != REF_STORAGE_FORMAT_FILES) + git_config_set("extensions.refstorage", + ref_storage_format_to_name(ref_storage_format)); +} + +static int is_reinit(void) +{ + struct strbuf buf = STRBUF_INIT; + char junk[2]; + int ret; + + git_path_buf(&buf, "HEAD"); + ret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1; + strbuf_release(&buf); + return ret; +} + +void create_reference_database(unsigned int ref_storage_format, + const char *initial_branch, int quiet) +{ + struct strbuf err = STRBUF_INIT; + int reinit = is_reinit(); + + repo_set_ref_storage_format(the_repository, ref_storage_format); + if (refs_init_db(get_main_ref_store(the_repository), 0, &err)) + die("failed to set up refs db: %s", err.buf); + + /* + * Point the HEAD symref to the initial branch with if HEAD does + * not yet exist. + */ + if (!reinit) { + char *ref; + + if (!initial_branch) + initial_branch = git_default_branch_name(quiet); + + ref = xstrfmt("refs/heads/%s", initial_branch); + if (check_refname_format(ref, 0) < 0) + die(_("invalid initial branch name: '%s'"), + initial_branch); + + if (create_symref("HEAD", ref, NULL) < 0) + exit(1); + free(ref); + } + + if (reinit && initial_branch) + warning(_("re-init: ignored --initial-branch=%s"), + initial_branch); + + strbuf_release(&err); } static int create_default_files(const char *template_path, const char *original_git_dir, - const char *initial_branch, const struct repository_format *fmt, int prev_bare_repository, - int init_shared_repository, - int quiet) + int init_shared_repository) { struct stat st1; struct strbuf buf = STRBUF_INIT; char *path; - char junk[2]; int reinit; int filemode; - struct strbuf err = STRBUF_INIT; const char *init_template_dir = NULL; const char *work_tree = get_git_work_tree(); @@ -1919,6 +1988,8 @@ static int create_default_files(const char *template_path, reset_shared_repository(); git_config(git_default_config, NULL); + reinit = is_reinit(); + /* * We must make sure command-line options continue to override any * values we might have just re-read from the config. @@ -1962,40 +2033,7 @@ static int create_default_files(const char *template_path, adjust_shared_perm(get_git_dir()); } - /* - * We need to create a "refs" dir in any case so that older - * versions of git can tell that this is a repository. - */ - safe_create_dir(git_path("refs"), 1); - adjust_shared_perm(git_path("refs")); - - if (refs_init_db(&err)) - die("failed to set up refs db: %s", err.buf); - - /* - * Point the HEAD symref to the initial branch with if HEAD does - * not yet exist. - */ - path = git_path_buf(&buf, "HEAD"); - reinit = (!access(path, R_OK) - || readlink(path, junk, sizeof(junk)-1) != -1); - if (!reinit) { - char *ref; - - if (!initial_branch) - initial_branch = git_default_branch_name(quiet); - - ref = xstrfmt("refs/heads/%s", initial_branch); - if (check_refname_format(ref, 0) < 0) - die(_("invalid initial branch name: '%s'"), - initial_branch); - - if (create_symref("HEAD", ref, NULL) < 0) - exit(1); - free(ref); - } - - initialize_repository_version(fmt->hash_algo, 0); + initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, 0); /* Check filemode trustability */ path = git_path_buf(&buf, "config"); @@ -2108,8 +2146,29 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash } } +static void validate_ref_storage_format(struct repository_format *repo_fmt, + unsigned int format) +{ + const char *name = getenv("GIT_DEFAULT_REF_FORMAT"); + + if (repo_fmt->version >= 0 && + format != REF_STORAGE_FORMAT_UNKNOWN && + format != repo_fmt->ref_storage_format) { + die(_("attempt to reinitialize repository with different reference storage format")); + } else if (format != REF_STORAGE_FORMAT_UNKNOWN) { + repo_fmt->ref_storage_format = format; + } else if (name) { + format = ref_storage_format_by_name(name); + if (format == REF_STORAGE_FORMAT_UNKNOWN) + die(_("unknown ref storage format '%s'"), name); + repo_fmt->ref_storage_format = format; + } +} + int init_db(const char *git_dir, const char *real_git_dir, - const char *template_dir, int hash, const char *initial_branch, + const char *template_dir, int hash, + unsigned int ref_storage_format, + const char *initial_branch, int init_shared_repository, unsigned int flags) { int reinit; @@ -2152,16 +2211,22 @@ int init_db(const char *git_dir, const char *real_git_dir, check_repository_format(&repo_fmt); validate_hash_algorithm(&repo_fmt, hash); + validate_ref_storage_format(&repo_fmt, ref_storage_format); reinit = create_default_files(template_dir, original_git_dir, - initial_branch, &repo_fmt, - prev_bare_repository, - init_shared_repository, - flags & INIT_DB_QUIET); - if (reinit && initial_branch) - warning(_("re-init: ignored --initial-branch=%s"), - initial_branch); + &repo_fmt, prev_bare_repository, + init_shared_repository); + + /* + * Now that we have set up both the hash algorithm and the ref storage + * format we can update the repository's settings accordingly. + */ + repo_set_hash_algo(the_repository, repo_fmt.hash_algo); + repo_set_ref_storage_format(the_repository, repo_fmt.ref_storage_format); + if (!(flags & INIT_DB_SKIP_REFDB)) + create_reference_database(repo_fmt.ref_storage_format, + initial_branch, flags & INIT_DB_QUIET); create_object_directory(); if (get_shared_repository()) { @@ -115,6 +115,7 @@ struct repository_format { int worktree_config; int is_bare; int hash_algo; + unsigned int ref_storage_format; int sparse_index; char *work_tree; struct string_list unknown_extensions; @@ -131,6 +132,7 @@ struct repository_format { .version = -1, \ .is_bare = -1, \ .hash_algo = GIT_HASH_SHA1, \ + .ref_storage_format = REF_STORAGE_FORMAT_FILES, \ .unknown_extensions = STRING_LIST_INIT_DUP, \ .v1_only_extensions = STRING_LIST_INIT_DUP, \ } @@ -169,14 +171,20 @@ int verify_repository_format(const struct repository_format *format, */ void check_repository_format(struct repository_format *fmt); -#define INIT_DB_QUIET 0x0001 -#define INIT_DB_EXIST_OK 0x0002 +#define INIT_DB_QUIET (1 << 0) +#define INIT_DB_EXIST_OK (1 << 1) +#define INIT_DB_SKIP_REFDB (1 << 2) int init_db(const char *git_dir, const char *real_git_dir, const char *template_dir, int hash_algo, + unsigned int ref_storage_format, const char *initial_branch, int init_shared_repository, unsigned int flags); -void initialize_repository_version(int hash_algo, int reinit); +void initialize_repository_version(int hash_algo, + unsigned int ref_storage_format, + int reinit); +void create_reference_database(unsigned int ref_storage_format, + const char *initial_branch, int quiet); /* * NOTE NOTE NOTE!! diff --git a/sh-i18n--envsubst.c b/sh-i18n--envsubst.c index 133496bd4d..f69fd16610 100644 --- a/sh-i18n--envsubst.c +++ b/sh-i18n--envsubst.c @@ -31,7 +31,7 @@ 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/>. */ + along with this program; if not, see <https://www.gnu.org/licenses/>. */ /* closeout.c - close standard output and standard error Copyright (C) 1998-2007 Free Software Foundation, Inc. @@ -47,7 +47,7 @@ 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/>. */ + along with this program; if not, see <https://www.gnu.org/licenses/>. */ #include <errno.h> #include <stdio.h> diff --git a/sha1dc/sha1.c b/sha1dc/sha1.c index dede2cbddf..f993ef9c69 100644 --- a/sha1dc/sha1.c +++ b/sha1dc/sha1.c @@ -88,7 +88,7 @@ /* * Should define Big Endian for a whitelist of known processors. See * https://sourceforge.net/p/predef/wiki/Endianness/ and - * http://www.oracle.com/technetwork/server-storage/solaris/portingtosolaris-138514.html + * https://web.archive.org/web/20140421151132/http://www.perforce.com/perforce/doc.current/manuals/p4sag/chapter.superuser.html */ #define SHA1DC_BIGENDIAN @@ -7,7 +7,6 @@ #include "commit.h" #include "tag.h" #include "pkt-line.h" -#include "remote.h" #include "refs.h" #include "oid-array.h" #include "path.h" diff --git a/shared.mak b/shared.mak index aeb80fc4d5..29bebd30d8 100644 --- a/shared.mak +++ b/shared.mak @@ -108,3 +108,11 @@ endif define mkdir_p_parent_template $(if $(wildcard $(@D)),,$(QUIET_MKDIR_P_PARENT)$(shell mkdir -p $(@D))) endef + +## Getting sick of writing -L$(SOMELIBDIR) $(CC_LD_DYNPATH)$(SOMELIBDIR)? +## Write $(call libpath_template,$(SOMELIBDIR)) instead, perhaps? +## With CC_LD_DYNPATH set to either an empty string or to "-L", the +## the directory is not shown the second time. +define libpath_template +-L$(1) $(if $(filter-out -L,$(CC_LD_DYNPATH)),$(CC_LD_DYNPATH)$(1)) +endef @@ -4,7 +4,6 @@ #include "strbuf.h" #include "run-command.h" #include "alias.h" -#include "prompt.h" #define COMMAND_DIR "git-shell-commands" #define HELP_COMMAND COMMAND_DIR "/help" diff --git a/sideband.c b/sideband.c index 6cbfd391c4..266a67342b 100644 --- a/sideband.c +++ b/sideband.c @@ -69,7 +69,10 @@ void list_config_color_sideband_slots(struct string_list *list, const char *pref * of the line. This should be called for a single line only, which is * passed as the first N characters of the SRC array. * - * NEEDSWORK: use "size_t n" instead for clarity. + * It is fine to use "int n" here instead of "size_t n" as all calls to this + * function pass an 'int' parameter. Additionally, the buffer involved in + * storing these 'int' values takes input from a packet via the pkt-line + * interface, which is capable of transferring only 64kB at a time. */ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n) { diff --git a/sparse-index.c b/sparse-index.c index 3578feb283..e48e40cae7 100644 --- a/sparse-index.c +++ b/sparse-index.c @@ -579,8 +579,9 @@ void expand_to_path(struct index_state *istate, replace++; temp = *replace; *replace = '\0'; + substr_len = replace - path_mutable.buf; if (index_file_exists(istate, path_mutable.buf, - path_mutable.len, icase)) { + substr_len, icase)) { /* * We found a parent directory in the name-hash * hashtable, because only sparse directory entries @@ -593,7 +594,6 @@ void expand_to_path(struct index_state *istate, } *replace = temp; - substr_len = replace - path_mutable.buf; } cleanup: diff --git a/statinfo.c b/statinfo.c index 9367ca099c..3c6bc049c1 100644 --- a/statinfo.c +++ b/statinfo.c @@ -31,6 +31,33 @@ void fill_stat_data(struct stat_data *sd, struct stat *st) sd->sd_size = munge_st_size(st->st_size); } +static void set_times(struct stat *st, const struct stat_data *sd) +{ + st->st_ctime = sd->sd_ctime.sec; + st->st_mtime = sd->sd_mtime.sec; +#ifdef NO_NSEC + ; /* nothing */ +#else +#ifdef USE_ST_TIMESPEC + st->st_ctimespec.tv_nsec = sd->sd_ctime.nsec; + st->st_mtimespec.tv_nsec = sd->sd_mtime.nsec; +#else + st->st_ctim.tv_nsec = sd->sd_ctime.nsec; + st->st_mtim.tv_nsec = sd->sd_mtime.nsec; +#endif +#endif +} + +void fake_lstat_data(const struct stat_data *sd, struct stat *st) +{ + set_times(st, sd); + st->st_dev = sd->sd_dev; + st->st_ino = sd->sd_ino; + st->st_uid = sd->sd_uid; + st->st_gid = sd->sd_gid; + st->st_size = sd->sd_size; +} + int match_stat_data(const struct stat_data *sd, struct stat *st) { int changed = 0; diff --git a/statinfo.h b/statinfo.h index 700f502ac0..5b21a30f90 100644 --- a/statinfo.h +++ b/statinfo.h @@ -47,6 +47,14 @@ struct stat_validity { void fill_stat_data(struct stat_data *sd, struct stat *st); /* + * The inverse of the above. When we know the cache_entry that + * contains sd is up-to-date, but still need to pretend we called + * lstat() to learn that fact, this function fills "st" enough to + * fool ie_match_stat(). + */ +void fake_lstat_data(const struct stat_data *sd, struct stat *st); + +/* * Return 0 if st is consistent with a file not having been changed * since sd was filled. If there are differences, return a * combination of MTIME_CHANGED, CTIME_CHANGED, OWNER_CHANGED, @@ -4,8 +4,8 @@ /** * The strvec API allows one to dynamically build and store * NULL-terminated arrays of strings. A strvec maintains the invariant that the - * `items` member always points to a non-NULL array, and that the array is - * always NULL-terminated at the element pointed to by `items[nr]`. This + * `v` member always points to a non-NULL array, and that the array is + * always NULL-terminated at the element pointed to by `v[nr]`. This * makes the result suitable for passing to functions expecting to receive * argv from main(). * @@ -22,7 +22,7 @@ extern const char *empty_strvec[]; /** * A single array. This should be initialized by assignment from - * `STRVEC_INIT`, or by calling `strvec_init`. The `items` + * `STRVEC_INIT`, or by calling `strvec_init`. The `v` * member contains the actual array; the `nr` member contains the * number of elements in the array, not including the terminating * NULL. @@ -80,7 +80,7 @@ void strvec_split(struct strvec *, const char *); void strvec_clear(struct strvec *); /** - * Disconnect the `items` member from the `strvec` struct and + * Disconnect the `v` member from the `strvec` struct and * return it. The caller is responsible for freeing the memory used * by the array, and by the strings it references. After detaching, * the `strvec` is in a reinitialized state and can be pushed diff --git a/submodule-config.c b/submodule-config.c index 6a48fd12f6..54130f6a38 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -14,6 +14,8 @@ #include "parse-options.h" #include "thread-utils.h" #include "tree-walk.h" +#include "url.h" +#include "urlmatch.h" /* * submodule cache lookup structure @@ -228,6 +230,144 @@ in_component: 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); +} + +static int submodule_url_is_relative(const char *url) +{ + return starts_with_dot_slash(url) || starts_with_dot_dot_slash(url); +} + +/* + * Count directory components that a relative submodule URL should chop + * from the remote_url it is to be resolved against. + * + * In other words, this counts "../" components at the start of a + * submodule URL. + * + * Returns the number of directory components to chop and writes a + * pointer to the next character of url after all leading "./" and + * "../" components to out. + */ +static int count_leading_dotdots(const char *url, const char **out) +{ + int result = 0; + while (1) { + if (starts_with_dot_dot_slash(url)) { + result++; + url += strlen("../"); + continue; + } + if (starts_with_dot_slash(url)) { + url += strlen("./"); + continue; + } + *out = url; + return result; + } +} +/* + * Check whether a transport is implemented by git-remote-curl. + * + * If it is, returns 1 and writes the URL that would be passed to + * git-remote-curl to the "out" parameter. + * + * Otherwise, returns 0 and leaves "out" untouched. + * + * Examples: + * http::https://example.com/repo.git -> 1, https://example.com/repo.git + * https://example.com/repo.git -> 1, https://example.com/repo.git + * git://example.com/repo.git -> 0 + * + * This is for use in checking for previously exploitable bugs that + * required a submodule URL to be passed to git-remote-curl. + */ +static int url_to_curl_url(const char *url, const char **out) +{ + /* + * We don't need to check for case-aliases, "http.exe", and so + * on because in the default configuration, is_transport_allowed + * prevents URLs with those schemes from being cloned + * automatically. + */ + if (skip_prefix(url, "http::", out) || + skip_prefix(url, "https::", out) || + skip_prefix(url, "ftp::", out) || + skip_prefix(url, "ftps::", out)) + return 1; + if (starts_with(url, "http://") || + starts_with(url, "https://") || + starts_with(url, "ftp://") || + starts_with(url, "ftps://")) { + *out = url; + return 1; + } + return 0; +} + +int check_submodule_url(const char *url) +{ + const char *curl_url; + + if (looks_like_command_line_option(url)) + return -1; + + if (submodule_url_is_relative(url) || starts_with(url, "git://")) { + char *decoded; + const char *next; + int has_nl; + + /* + * This could be appended to an http URL and url-decoded; + * check for malicious characters. + */ + decoded = url_decode(url); + has_nl = !!strchr(decoded, '\n'); + + free(decoded); + if (has_nl) + return -1; + + /* + * URLs which escape their root via "../" can overwrite + * the host field and previous components, resolving to + * URLs like https::example.com/submodule.git and + * https:///example.com/submodule.git that were + * susceptible to CVE-2020-11008. + */ + if (count_leading_dotdots(url, &next) > 0 && + (*next == ':' || *next == '/')) + return -1; + } + + else if (url_to_curl_url(url, &curl_url)) { + int ret = 0; + char *normalized = url_normalize(curl_url, NULL); + if (normalized) { + char *decoded = url_decode(normalized); + if (strchr(decoded, '\n')) + ret = -1; + free(normalized); + free(decoded); + } else { + ret = -1; + } + + return ret; + } + + return 0; +} + static int name_and_item_from_var(const char *var, struct strbuf *name, struct strbuf *item) { @@ -516,7 +656,9 @@ static int parse_config(const char *var, const char *value, submodule->recommend_shallow = git_config_bool(var, value); } else if (!strcmp(item.buf, "branch")) { - if (!me->overwrite && submodule->branch) + if (!value) + ret = config_error_nonbool(var); + else if (!me->overwrite && submodule->branch) warn_multiple_config(me->treeish_name, submodule->name, "branch"); else { diff --git a/submodule-config.h b/submodule-config.h index 2a37689cc2..b6133af71b 100644 --- a/submodule-config.h +++ b/submodule-config.h @@ -2,9 +2,7 @@ #define SUBMODULE_CONFIG_CACHE_H #include "config.h" -#include "hashmap.h" #include "submodule.h" -#include "strbuf.h" #include "tree-walk.h" /** @@ -91,6 +89,9 @@ int config_set_in_gitmodules_file_gently(const char *key, const char *value); */ int check_submodule_name(const char *name); +/* Returns 0 if the URL valid per RFC3986 and -1 otherwise. */ +int check_submodule_url(const char *url); + /* * Note: these helper functions exist solely to maintain backward * compatibility with 'fetch' and 'update_clone' storing configuration in diff --git a/submodule.c b/submodule.c index e603a19a87..40f13a3685 100644 --- a/submodule.c +++ b/submodule.c @@ -17,10 +17,8 @@ #include "string-list.h" #include "oid-array.h" #include "strvec.h" -#include "blob.h" #include "thread-utils.h" #include "path.h" -#include "quote.h" #include "remote.h" #include "worktree.h" #include "parse-options.h" @@ -30,7 +28,6 @@ #include "commit-reach.h" #include "read-cache-ll.h" #include "setup.h" -#include "shallow.h" #include "trace2.h" static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF; @@ -1690,8 +1687,6 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, task = get_fetch_task_from_changed(spf, err); if (task) { - struct strbuf submodule_prefix = STRBUF_INIT; - child_process_init(cp); cp->dir = task->repo->gitdir; prepare_submodule_repo_env_in_gitdir(&cp->env); @@ -1701,15 +1696,11 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, strvec_pushv(&cp->args, task->git_args.v); strvec_pushv(&cp->args, spf->args.v); strvec_push(&cp->args, task->default_argv); - strvec_push(&cp->args, "--submodule-prefix"); + strvec_pushf(&cp->args, "--submodule-prefix=%s%s/", + spf->prefix, task->sub->path); - strbuf_addf(&submodule_prefix, "%s%s/", - spf->prefix, - task->sub->path); - strvec_push(&cp->args, submodule_prefix.buf); *task_cb = task; - strbuf_release(&submodule_prefix); string_list_insert(&spf->seen_submodule_names, task->sub->name); return 1; } @@ -1717,12 +1708,8 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, if (spf->oid_fetch_tasks_nr) { struct fetch_task *task = spf->oid_fetch_tasks[spf->oid_fetch_tasks_nr - 1]; - struct strbuf submodule_prefix = STRBUF_INIT; spf->oid_fetch_tasks_nr--; - strbuf_addf(&submodule_prefix, "%s%s/", - spf->prefix, task->sub->path); - child_process_init(cp); prepare_submodule_repo_env_in_gitdir(&cp->env); cp->git_cmd = 1; @@ -1731,8 +1718,8 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, strvec_init(&cp->args); strvec_pushv(&cp->args, spf->args.v); strvec_push(&cp->args, "on-demand"); - strvec_push(&cp->args, "--submodule-prefix"); - strvec_push(&cp->args, submodule_prefix.buf); + strvec_pushf(&cp->args, "--submodule-prefix=%s%s/", + spf->prefix, task->sub->path); /* NEEDSWORK: have get_default_remote from submodule--helper */ strvec_push(&cp->args, "origin"); @@ -1740,7 +1727,6 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, append_oid_to_argv, &cp->args); *task_cb = task; - strbuf_release(&submodule_prefix); return 1; } diff --git a/t/Makefile b/t/Makefile index 3e00cdd801..2d95046f26 100644 --- a/t/Makefile +++ b/t/Makefile @@ -1,3 +1,6 @@ +# The default target of this Makefile is... +all:: + # Import tree-wide shared Makefile behavior and libraries include ../shared.mak @@ -6,6 +9,7 @@ include ../shared.mak # Copyright (c) 2005 Junio C Hamano # +-include ../config.mak.uname -include ../config.mak.autogen -include ../config.mak @@ -17,6 +21,7 @@ TAR ?= $(TAR) RM ?= rm -f PROVE ?= prove DEFAULT_TEST_TARGET ?= test +DEFAULT_UNIT_TEST_TARGET ?= unit-tests-raw TEST_LINT ?= test-lint ifdef TEST_OUTPUT_DIRECTORY @@ -41,13 +46,16 @@ TPERF = $(sort $(wildcard perf/p[0-9][0-9][0-9][0-9]-*.sh)) TINTEROP = $(sort $(wildcard interop/i[0-9][0-9][0-9][0-9]-*.sh)) CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.test))) CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl +UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c) +UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%$(X),$(UNIT_TEST_SOURCES)) +UNIT_TESTS = $(sort $(filter-out unit-tests/bin/t-basic%,$(UNIT_TEST_PROGRAMS))) # `test-chainlint` (which is a dependency of `test-lint`, `test` and `prove`) # checks all tests in all scripts via a single invocation, so tell individual # scripts not to run the external "chainlint.pl" script themselves CHAINLINTSUPPRESS = GIT_TEST_EXT_CHAIN_LINT=0 && export GIT_TEST_EXT_CHAIN_LINT && -all: $(DEFAULT_TEST_TARGET) +all:: $(DEFAULT_TEST_TARGET) test: pre-clean check-chainlint $(TEST_LINT) $(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup @@ -65,6 +73,17 @@ prove: pre-clean check-chainlint $(TEST_LINT) $(T): @echo "*** $@ ***"; '$(TEST_SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) +$(UNIT_TESTS): + @echo "*** $@ ***"; $@ + +.PHONY: unit-tests unit-tests-raw unit-tests-prove +unit-tests: $(DEFAULT_UNIT_TEST_TARGET) + +unit-tests-raw: $(UNIT_TESTS) + +unit-tests-prove: + @echo "*** prove - unit tests ***"; $(PROVE) $(GIT_PROVE_OPTS) $(UNIT_TESTS) + pre-clean: $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' @@ -90,20 +109,12 @@ check-chainlint: echo "# chainlint: $(CHAINLINTTMP_SQ)/tests" && \ for i in $(CHAINLINTTESTS); do \ echo "# chainlint: $$i" && \ - sed -e '/^[ ]*$$/d' chainlint/$$i.expect; \ + cat chainlint/$$i.expect; \ done \ } >'$(CHAINLINTTMP_SQ)'/expect && \ $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests | \ - sed -e 's/^[1-9][0-9]* //;/^[ ]*$$/d' >'$(CHAINLINTTMP_SQ)'/actual && \ - if test -f ../GIT-BUILD-OPTIONS; then \ - . ../GIT-BUILD-OPTIONS; \ - fi && \ - if test -x ../git$$X; then \ - DIFFW="../git$$X --no-pager diff -w --no-index"; \ - else \ - DIFFW="diff -w -u"; \ - fi && \ - $$DIFFW '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual + sed -e 's/^[1-9][0-9]* //' >'$(CHAINLINTTMP_SQ)'/actual && \ + diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \ test-lint-filenames @@ -149,4 +160,4 @@ perf: $(MAKE) -C perf/ all .PHONY: pre-clean $(T) aggregate-results clean valgrind perf \ - check-chainlint clean-chainlint test-chainlint + check-chainlint clean-chainlint test-chainlint $(UNIT_TESTS) @@ -32,7 +32,7 @@ the tests. ok 2 - plain with GIT_WORK_TREE ok 3 - plain bare -Since the tests all output TAP (see http://testanything.org) they can +Since the tests all output TAP (see https://testanything.org) they can be run with any TAP harness. Here's an example of parallel testing powered by a recent version of prove(1): @@ -479,6 +479,9 @@ GIT_TEST_DEFAULT_HASH=<hash-algo> specifies which hash algorithm to use in the test scripts. Recognized values for <hash-algo> are "sha1" and "sha256". +GIT_TEST_DEFAULT_REF_FORMAT=<format> specifies which ref storage format +to use in the test scripts. Recognized values for <format> are "files". + GIT_TEST_NO_WRITE_REV_INDEX=<boolean>, when true disables the 'pack.writeReverseIndex' setting. @@ -1278,7 +1281,7 @@ Devel::Cover module. To install it do: sudo aptitude install libdevel-cover-perl # From the CPAN with cpanminus - curl -L http://cpanmin.us | perl - --sudo --self-upgrade + curl -L https://cpanmin.us/ | perl - --sudo --self-upgrade cpanm --sudo Devel::Cover Then, at the top-level: diff --git a/t/chainlint/blank-line-before-esac.expect b/t/chainlint/blank-line-before-esac.expect index 48ed4eb124..056e03003d 100644 --- a/t/chainlint/blank-line-before-esac.expect +++ b/t/chainlint/blank-line-before-esac.expect @@ -1,11 +1,11 @@ -test_done ( ) { +test_done () { case "$test_failure" in - 0 ) + 0) test_at_end_hook_ exit 0 ;; - * ) + *) if test $test_external_has_tap -eq 0 then say_color error "# failed $test_failure among $msg" @@ -14,5 +14,5 @@ test_done ( ) { exit 1 ;; - esac + esac } diff --git a/t/chainlint/blank-line.expect b/t/chainlint/blank-line.expect index f76fde1ffb..b47827d749 100644 --- a/t/chainlint/blank-line.expect +++ b/t/chainlint/blank-line.expect @@ -1,4 +1,8 @@ ( + nothing && + something + + ) diff --git a/t/chainlint/block.expect b/t/chainlint/block.expect index a3bcea492a..1c87326364 100644 --- a/t/chainlint/block.expect +++ b/t/chainlint/block.expect @@ -12,9 +12,9 @@ ) && { - echo a ; ?!AMP?! echo b + echo a; ?!AMP?! echo b } && -{ echo a ; ?!AMP?! echo b ; } && +{ echo a; ?!AMP?! echo b; } && { echo "${var}9" && diff --git a/t/chainlint/chain-break-background.expect b/t/chainlint/chain-break-background.expect index 28f9114f42..20d0bb5333 100644 --- a/t/chainlint/chain-break-background.expect +++ b/t/chainlint/chain-break-background.expect @@ -1,9 +1,9 @@ JGIT_DAEMON_PID= && git init --bare empty.git && -> empty.git/git-daemon-export-ok && +>empty.git/git-daemon-export-ok && mkfifo jgit_daemon_output && { - jgit daemon --port="$JGIT_DAEMON_PORT" . > jgit_daemon_output & + jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output & JGIT_DAEMON_PID=$! } && test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git diff --git a/t/chainlint/chain-break-return-exit.expect b/t/chainlint/chain-break-return-exit.expect index 1732d221c3..4cd18e2edf 100644 --- a/t/chainlint/chain-break-return-exit.expect +++ b/t/chainlint/chain-break-return-exit.expect @@ -1,16 +1,16 @@ case "$(git ls-files)" in -one ) echo pass one ;; -* ) echo bad one ; return 1 ;; +one) echo pass one ;; +*) echo bad one; return 1 ;; esac && ( case "$(git ls-files)" in - two ) echo pass two ;; - * ) echo bad two ; exit 1 ;; -esac + two) echo pass two ;; + *) echo bad two; exit 1 ;; + esac ) && case "$(git ls-files)" in -dir/two"$LF"one ) echo pass both ;; -* ) echo bad ; return 1 ;; +dir/two"$LF"one) echo pass both ;; +*) echo bad; return 1 ;; esac && for i in 1 2 3 4 ; do diff --git a/t/chainlint/chain-break-status.expect b/t/chainlint/chain-break-status.expect index f4bada9463..e6b3b2193e 100644 --- a/t/chainlint/chain-break-status.expect +++ b/t/chainlint/chain-break-status.expect @@ -1,7 +1,7 @@ -OUT=$(( ( large_git ; echo $? 1 >& 3 ) | : ) 3 >& 1) && +OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) && test_match_signal 13 "$OUT" && -{ test-tool sigchain > actual ; ret=$? ; } && +{ test-tool sigchain >actual; ret=$?; } && { test_match_signal 15 "$ret" || test "$ret" = 3 diff --git a/t/chainlint/chained-subshell.expect b/t/chainlint/chained-subshell.expect index af0369d328..83810ea7ec 100644 --- a/t/chainlint/chained-subshell.expect +++ b/t/chainlint/chained-subshell.expect @@ -4,7 +4,7 @@ mkdir sub && ( nuff said ) && -cut "-d " -f actual | ( read s1 s2 s3 && +cut "-d " -f actual | (read s1 s2 s3 && test -f $s1 ?!AMP?! test $(cat $s2) = tree2path1 && -test $(cat $s3) = tree3path1 ) +test $(cat $s3) = tree3path1) diff --git a/t/chainlint/command-substitution-subsubshell.expect b/t/chainlint/command-substitution-subsubshell.expect index ab2f79e845..ec42f2c30c 100644 --- a/t/chainlint/command-substitution-subsubshell.expect +++ b/t/chainlint/command-substitution-subsubshell.expect @@ -1,2 +1,2 @@ -OUT=$(( ( large_git 1 >& 3 ) | : ) 3 >& 1) && +OUT=$( ((large_git 1>&3) | :) 3>&1 ) && test_match_signal 13 "$OUT" diff --git a/t/chainlint/dqstring-line-splice.expect b/t/chainlint/dqstring-line-splice.expect index bf9ced60d4..37eab80738 100644 --- a/t/chainlint/dqstring-line-splice.expect +++ b/t/chainlint/dqstring-line-splice.expect @@ -1,3 +1,5 @@ -echo 'fatal: reword option of --fixup is mutually exclusive with' '--patch/--interactive/--all/--include/--only' > expect && -test_must_fail git commit --fixup=reword:HEAD~ $1 2 > actual && + +echo 'fatal: reword option of --fixup is mutually exclusive with' '--patch/--interactive/--all/--include/--only' >expect && +test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual && test_cmp expect actual + diff --git a/t/chainlint/dqstring-no-interpolate.expect b/t/chainlint/dqstring-no-interpolate.expect index 10724987a5..087eda15e4 100644 --- a/t/chainlint/dqstring-no-interpolate.expect +++ b/t/chainlint/dqstring-no-interpolate.expect @@ -6,6 +6,7 @@ grep "^\.git$" output.txt && ( cd client$version && GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. $(cat ../input) -) > output && - cut -d ' ' -f 2 < output | sort > actual && +) >output && + cut -d ' ' -f 2 <output | sort >actual && test_cmp expect actual + diff --git a/t/chainlint/empty-here-doc.expect b/t/chainlint/empty-here-doc.expect index e8733c97c6..8507721192 100644 --- a/t/chainlint/empty-here-doc.expect +++ b/t/chainlint/empty-here-doc.expect @@ -1,4 +1,4 @@ -git ls-tree $tree path > current && -cat > expected <<\EOF && +git ls-tree $tree path >current && +cat >expected <<\EOF && EOF test_output diff --git a/t/chainlint/exclamation.expect b/t/chainlint/exclamation.expect index 2d961a58c6..765a35bb4c 100644 --- a/t/chainlint/exclamation.expect +++ b/t/chainlint/exclamation.expect @@ -1,4 +1,4 @@ -if ! condition ; then echo nope ; else yep ; fi && +if ! condition; then echo nope; else yep; fi && test_prerequisite !MINGW && mail uucp!address && echo !whatever! diff --git a/t/chainlint/for-loop-abbreviated.expect b/t/chainlint/for-loop-abbreviated.expect index a21007a63f..02c0d15cca 100644 --- a/t/chainlint/for-loop-abbreviated.expect +++ b/t/chainlint/for-loop-abbreviated.expect @@ -1,5 +1,5 @@ for it do - path=$(expr "$it" : ( [^:]*) ) && + path=$(expr "$it" : ([^:]*)) && git update-index --add "$path" || exit done diff --git a/t/chainlint/for-loop.expect b/t/chainlint/for-loop.expect index d65c82129a..d2237f1e38 100644 --- a/t/chainlint/for-loop.expect +++ b/t/chainlint/for-loop.expect @@ -6,6 +6,7 @@ bar EOF done ?!AMP?! + for i in a b c; do echo $i && cat $i ?!LOOP?! diff --git a/t/chainlint/function.expect b/t/chainlint/function.expect index a14388e6b9..dd7c997a3c 100644 --- a/t/chainlint/function.expect +++ b/t/chainlint/function.expect @@ -1,8 +1,8 @@ -sha1_file ( ) { +sha1_file() { echo "$*" | sed "s#..#.git/objects/&/#" } && -remove_object ( ) { +remove_object() { file=$(sha1_file "$*") && test -e "$file" ?!AMP?! rm -f "$file" diff --git a/t/chainlint/here-doc.expect b/t/chainlint/here-doc.expect index 1df3f78282..91b961242a 100644 --- a/t/chainlint/here-doc.expect +++ b/t/chainlint/here-doc.expect @@ -1,6 +1,6 @@ boodle wobba \ - gorgo snoot \ - wafta snurb <<EOF && + gorgo snoot \ + wafta snurb <<EOF && quoth the raven, nevermore... EOF diff --git a/t/chainlint/loop-detect-status.expect b/t/chainlint/loop-detect-status.expect index 24da9e86d5..7ce3a34806 100644 --- a/t/chainlint/loop-detect-status.expect +++ b/t/chainlint/loop-detect-status.expect @@ -1,18 +1,18 @@ -( while test $i -le $blobcount -do - printf "Generating blob $i/$blobcount\r" >& 2 && +(while test $i -le $blobcount + do + printf "Generating blob $i/$blobcount\r" >&2 && printf "blob\nmark :$i\ndata $blobsize\n" && #test-tool genrandom $i $blobsize && printf "%-${blobsize}s" $i && echo "M 100644 :$i $i" >> commit && i=$(($i+1)) || echo $? > exit-status -done && -echo "commit refs/heads/main" && -echo "author A U Thor <author@email.com> 123456789 +0000" && -echo "committer C O Mitter <committer@email.com> 123456789 +0000" && -echo "data 5" && -echo ">2gb" && -cat commit ) | + done && + echo "commit refs/heads/main" && + echo "author A U Thor <author@email.com> 123456789 +0000" && + echo "committer C O Mitter <committer@email.com> 123456789 +0000" && + echo "data 5" && + echo ">2gb" && + cat commit) | git fast-import --big-file-threshold=2 && test ! -f exit-status diff --git a/t/chainlint/nested-cuddled-subshell.expect b/t/chainlint/nested-cuddled-subshell.expect index 2a86885ee6..3836049cc4 100644 --- a/t/chainlint/nested-cuddled-subshell.expect +++ b/t/chainlint/nested-cuddled-subshell.expect @@ -2,18 +2,24 @@ (cd foo && bar ) && + (cd foo && bar ) ?!AMP?! + ( cd foo && bar) && + ( cd foo && bar) ?!AMP?! + (cd foo && bar) && + (cd foo && bar) ?!AMP?! + foobar ) diff --git a/t/chainlint/nested-loop-detect-failure.expect b/t/chainlint/nested-loop-detect-failure.expect index 4793a0e8e1..3461df40e5 100644 --- a/t/chainlint/nested-loop-detect-failure.expect +++ b/t/chainlint/nested-loop-detect-failure.expect @@ -1,31 +1,31 @@ -for i in 0 1 2 3 4 5 6 7 8 9 ; +for i in 0 1 2 3 4 5 6 7 8 9; do - for j in 0 1 2 3 4 5 6 7 8 9 ; + for j in 0 1 2 3 4 5 6 7 8 9; do - echo "$i$j" > "path$i$j" ?!LOOP?! + echo "$i$j" >"path$i$j" ?!LOOP?! done ?!LOOP?! done && -for i in 0 1 2 3 4 5 6 7 8 9 ; +for i in 0 1 2 3 4 5 6 7 8 9; do - for j in 0 1 2 3 4 5 6 7 8 9 ; + for j in 0 1 2 3 4 5 6 7 8 9; do - echo "$i$j" > "path$i$j" || return 1 + echo "$i$j" >"path$i$j" || return 1 done done && -for i in 0 1 2 3 4 5 6 7 8 9 ; +for i in 0 1 2 3 4 5 6 7 8 9; do - for j in 0 1 2 3 4 5 6 7 8 9 ; + for j in 0 1 2 3 4 5 6 7 8 9; do - echo "$i$j" > "path$i$j" ?!LOOP?! + echo "$i$j" >"path$i$j" ?!LOOP?! done || return 1 done && -for i in 0 1 2 3 4 5 6 7 8 9 ; +for i in 0 1 2 3 4 5 6 7 8 9; do - for j in 0 1 2 3 4 5 6 7 8 9 ; + for j in 0 1 2 3 4 5 6 7 8 9; do - echo "$i$j" > "path$i$j" || return 1 + echo "$i$j" >"path$i$j" || return 1 done || return 1 done diff --git a/t/chainlint/nested-subshell.expect b/t/chainlint/nested-subshell.expect index 02e0a9f1bb..73ff28546a 100644 --- a/t/chainlint/nested-subshell.expect +++ b/t/chainlint/nested-subshell.expect @@ -4,6 +4,7 @@ echo a && echo b ) >file && + cd foo && ( echo a ?!AMP?! diff --git a/t/chainlint/pipe.expect b/t/chainlint/pipe.expect index 2cfc028297..811971b1a3 100644 --- a/t/chainlint/pipe.expect +++ b/t/chainlint/pipe.expect @@ -2,7 +2,9 @@ foo | bar | baz && + fish | cow ?!AMP?! + sunder ) diff --git a/t/chainlint/subshell-here-doc.expect b/t/chainlint/subshell-here-doc.expect index 52789278d1..75d6f607e2 100644 --- a/t/chainlint/subshell-here-doc.expect +++ b/t/chainlint/subshell-here-doc.expect @@ -1,7 +1,7 @@ ( echo wobba \ - gorgo snoot \ - wafta snurb <<-EOF && + gorgo snoot \ + wafta snurb <<-EOF && quoth the raven, nevermore... EOF diff --git a/t/chainlint/subshell-one-liner.expect b/t/chainlint/subshell-one-liner.expect index b7015361bf..8f694990e8 100644 --- a/t/chainlint/subshell-one-liner.expect +++ b/t/chainlint/subshell-one-liner.expect @@ -2,13 +2,18 @@ (foo && bar) && (foo && bar) | (foo && bar) >baz && + (foo; ?!AMP?! bar) && (foo; ?!AMP?! bar) | (foo; ?!AMP?! bar) >baz && + (foo || exit 1) && (foo || exit 1) | (foo || exit 1) >baz && + (foo && bar) ?!AMP?! + (foo && bar; ?!AMP?! baz) ?!AMP?! + foobar ) diff --git a/t/chainlint/t7900-subtree.expect b/t/chainlint/t7900-subtree.expect index 71b3b3bc20..02f3129232 100644 --- a/t/chainlint/t7900-subtree.expect +++ b/t/chainlint/t7900-subtree.expect @@ -15,6 +15,7 @@ main-sub4" && $chkms TXT ) && + subfiles=$(git ls-files) && check_equal "$subfiles" "$chkms $chks" diff --git a/t/chainlint/token-pasting.expect b/t/chainlint/token-pasting.expect index 342360bcd0..6a387917a7 100644 --- a/t/chainlint/token-pasting.expect +++ b/t/chainlint/token-pasting.expect @@ -4,22 +4,22 @@ git config filter.rot13.clean ./rot13.sh && { echo "*.t filter=rot13" ?!AMP?! echo "*.i ident" -} > .gitattributes && +} >.gitattributes && { echo a b c d e f g h i j k l m ?!AMP?! echo n o p q r s t u v w x y z ?!AMP?! echo '$Id$' -} > test && -cat test > test.t && -cat test > test.o && -cat test > test.i && +} >test && +cat test >test.t && +cat test >test.o && +cat test >test.i && git add test test.t test.i && rm -f test test.t test.i && git checkout -- test test.t test.i && -echo "content-test2" > test2.o && -echo "content-test3 - filename with special characters" > "test3 'sq',$x=.o" ?!AMP?! +echo "content-test2" >test2.o && +echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!AMP?! downstream_url_for_sed=$( printf "%sn" "$downstream_url" | diff --git a/t/chainlint/while-loop.expect b/t/chainlint/while-loop.expect index 1f5eaea0fd..06c1567f48 100644 --- a/t/chainlint/while-loop.expect +++ b/t/chainlint/while-loop.expect @@ -6,6 +6,7 @@ bar EOF done ?!AMP?! + while true; do echo foo && cat bar ?!LOOP?! diff --git a/t/helper/test-bundle-uri.c b/t/helper/test-bundle-uri.c index 475058592d..09dc78733c 100644 --- a/t/helper/test-bundle-uri.c +++ b/t/helper/test-bundle-uri.c @@ -5,9 +5,7 @@ #include "strbuf.h" #include "string-list.h" #include "transport.h" -#include "ref-filter.h" #include "remote.h" -#include "refs.h" enum input_mode { KEY_VALUE_PAIRS, diff --git a/t/helper/test-ctype.c b/t/helper/test-ctype.c deleted file mode 100644 index e5659df40b..0000000000 --- a/t/helper/test-ctype.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "test-tool.h" - -static int rc; - -static void report_error(const char *class, int ch) -{ - printf("%s classifies char %d (0x%02x) wrongly\n", class, ch, ch); - rc = 1; -} - -static int is_in(const char *s, int ch) -{ - /* - * We can't find NUL using strchr. Accept it as the first - * character in the spec -- there are no empty classes. - */ - if (ch == '\0') - return ch == *s; - if (*s == '\0') - s++; - return !!strchr(s, ch); -} - -#define TEST_CLASS(t,s) { \ - int i; \ - for (i = 0; i < 256; i++) { \ - if (is_in(s, i) != t(i)) \ - report_error(#t, i); \ - } \ - if (t(EOF)) \ - report_error(#t, EOF); \ -} - -#define DIGIT "0123456789" -#define LOWER "abcdefghijklmnopqrstuvwxyz" -#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define PUNCT "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" -#define ASCII \ - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ - "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ - "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ - "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ - "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" \ - "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ - "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" -#define CNTRL \ - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ - "\x7f" - -int cmd__ctype(int argc UNUSED, const char **argv UNUSED) -{ - TEST_CLASS(isdigit, DIGIT); - TEST_CLASS(isspace, " \n\r\t"); - TEST_CLASS(isalpha, LOWER UPPER); - TEST_CLASS(isalnum, LOWER UPPER DIGIT); - TEST_CLASS(is_glob_special, "*?[\\"); - TEST_CLASS(is_regex_special, "$()*+.?[\\^{|"); - TEST_CLASS(is_pathspec_magic, "!\"#%&',-/:;<=>@_`~"); - TEST_CLASS(isascii, ASCII); - TEST_CLASS(islower, LOWER); - TEST_CLASS(isupper, UPPER); - TEST_CLASS(iscntrl, CNTRL); - TEST_CLASS(ispunct, PUNCT); - TEST_CLASS(isxdigit, DIGIT "abcdefABCDEF"); - TEST_CLASS(isprint, LOWER UPPER DIGIT PUNCT " "); - - return rc; -} diff --git a/t/helper/test-fast-rebase.c b/t/helper/test-fast-rebase.c deleted file mode 100644 index cac20a72b3..0000000000 --- a/t/helper/test-fast-rebase.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * "git fast-rebase" builtin command - * - * FAST: Forking Any Subprocesses (is) Taboo - * - * This is meant SOLELY as a demo of what is possible. sequencer.c and - * rebase.c should be refactored to use the ideas here, rather than attempting - * to extend this file to replace those (unless Phillip or Dscho say that - * refactoring is too hard and we need a clean slate, but I'm guessing that - * refactoring is the better route). - */ - -#define USE_THE_INDEX_VARIABLE -#include "test-tool.h" -#include "cache-tree.h" -#include "commit.h" -#include "environment.h" -#include "gettext.h" -#include "hash.h" -#include "hex.h" -#include "lockfile.h" -#include "merge-ort.h" -#include "object-name.h" -#include "read-cache-ll.h" -#include "refs.h" -#include "revision.h" -#include "sequencer.h" -#include "setup.h" -#include "strvec.h" -#include "tree.h" - -static const char *short_commit_name(struct commit *commit) -{ - return repo_find_unique_abbrev(the_repository, &commit->object.oid, - DEFAULT_ABBREV); -} - -static struct commit *peel_committish(const char *name) -{ - struct object *obj; - struct object_id oid; - - if (repo_get_oid(the_repository, name, &oid)) - return NULL; - obj = parse_object(the_repository, &oid); - return (struct commit *)repo_peel_to_type(the_repository, name, 0, obj, - OBJ_COMMIT); -} - -static char *get_author(const char *message) -{ - size_t len; - const char *a; - - a = find_commit_header(message, "author", &len); - if (a) - return xmemdupz(a, len); - - return NULL; -} - -static struct commit *create_commit(struct tree *tree, - struct commit *based_on, - struct commit *parent) -{ - struct object_id ret; - struct object *obj; - struct commit_list *parents = NULL; - char *author; - char *sign_commit = NULL; - struct commit_extra_header *extra; - struct strbuf msg = STRBUF_INIT; - const char *out_enc = get_commit_output_encoding(); - const char *message = repo_logmsg_reencode(the_repository, based_on, - NULL, out_enc); - const char *orig_message = NULL; - const char *exclude_gpgsig[] = { "gpgsig", NULL }; - - commit_list_insert(parent, &parents); - extra = read_commit_extra_headers(based_on, exclude_gpgsig); - find_commit_subject(message, &orig_message); - strbuf_addstr(&msg, orig_message); - author = get_author(message); - reset_ident_date(); - if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents, - &ret, author, NULL, sign_commit, extra)) { - error(_("failed to write commit object")); - return NULL; - } - free(author); - strbuf_release(&msg); - - obj = parse_object(the_repository, &ret); - return (struct commit *)obj; -} - -int cmd__fast_rebase(int argc, const char **argv) -{ - struct commit *onto; - struct commit *last_commit = NULL, *last_picked_commit = NULL; - struct object_id head; - struct lock_file lock = LOCK_INIT; - struct strvec rev_walk_args = STRVEC_INIT; - struct rev_info revs; - struct commit *commit; - struct merge_options merge_opt; - struct tree *next_tree, *base_tree, *head_tree; - 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 - * do that manually. - */ - setup_git_directory(); - - if (argc == 2 && !strcmp(argv[1], "-h")) { - printf("Sorry, I am not a psychiatrist; I can not give you the help you need. Oh, you meant usage...\n"); - exit(129); - } - - if (argc != 5 || strcmp(argv[1], "--onto")) - die("usage: read the code, figure out how to use it, then do so"); - - onto = peel_committish(argv[2]); - strbuf_addf(&branch_name, "refs/heads/%s", argv[4]); - - /* Sanity check */ - if (repo_get_oid(the_repository, "HEAD", &head)) - die(_("Cannot read HEAD")); - assert(oideq(&onto->object.oid, &head)); - - repo_hold_locked_index(the_repository, &lock, LOCK_DIE_ON_ERROR); - if (repo_read_index(the_repository) < 0) - BUG("Could not read index"); - - repo_init_revisions(the_repository, &revs, NULL); - revs.verbose_header = 1; - revs.max_parents = 1; - revs.cherry_mark = 1; - revs.limited = 1; - revs.reverse = 1; - revs.right_only = 1; - revs.sort_order = REV_SORT_IN_GRAPH_ORDER; - 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) { - ret = error(_("unhandled options")); - goto cleanup; - } - - strvec_clear(&rev_walk_args); - - 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)); - merge_opt.show_rename_progress = 1; - merge_opt.branch1 = "HEAD"; - head_tree = repo_get_commit_tree(the_repository, onto); - result.tree = head_tree; - last_commit = onto; - while ((commit = get_revision(&revs))) { - struct commit *base; - - fprintf(stderr, "Rebasing %s...\r", - oid_to_hex(&commit->object.oid)); - assert(commit->parents && !commit->parents->next); - base = commit->parents->item; - - next_tree = repo_get_commit_tree(the_repository, commit); - base_tree = repo_get_commit_tree(the_repository, base); - - merge_opt.branch2 = short_commit_name(commit); - merge_opt.ancestor = xstrfmt("parent of %s", merge_opt.branch2); - - merge_incore_nonrecursive(&merge_opt, - base_tree, - result.tree, - next_tree, - &result); - - free((char*)merge_opt.ancestor); - merge_opt.ancestor = NULL; - if (!result.clean) - break; - last_picked_commit = commit; - last_commit = create_commit(result.tree, commit, last_commit); - } - - merge_switch_to_result(&merge_opt, head_tree, &result, 1, !result.clean); - - if (result.clean < 0) - exit(128); - - if (result.clean) { - fprintf(stderr, "\nDone.\n"); - strbuf_addf(&reflog_msg, "finish rebase %s onto %s", - oid_to_hex(&last_picked_commit->object.oid), - oid_to_hex(&last_commit->object.oid)); - if (update_ref(reflog_msg.buf, branch_name.buf, - &last_commit->object.oid, - &last_picked_commit->object.oid, - REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { - error(_("could not update %s"), argv[4]); - die("Failed to update %s", argv[4]); - } - if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0) - die(_("unable to update HEAD")); - - prime_cache_tree(the_repository, the_repository->index, - result.tree); - } else { - fprintf(stderr, "\nAborting: Hit a conflict.\n"); - strbuf_addf(&reflog_msg, "rebase progress up to %s", - oid_to_hex(&last_picked_commit->object.oid)); - if (update_ref(reflog_msg.buf, "HEAD", - &last_commit->object.oid, - &head, - REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) { - error(_("could not update %s"), argv[4]); - die("Failed to update %s", argv[4]); - } - } - if (write_locked_index(&the_index, &lock, - COMMIT_LOCK | SKIP_IF_UNCHANGED)) - die(_("unable to write %s"), get_index_file()); - - ret = (result.clean == 0); -cleanup: - strbuf_release(&reflog_msg); - strbuf_release(&branch_name); - release_revisions(&revs); - return ret; -} diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c index f4d134a145..4daa82f00f 100644 --- a/t/helper/test-pkt-line.c +++ b/t/helper/test-pkt-line.c @@ -1,7 +1,9 @@ #include "git-compat-util.h" #include "test-tool.h" #include "pkt-line.h" +#include "sideband.h" #include "write-or-die.h" +#include "parse-options.h" static void pack_line(const char *line) { @@ -64,12 +66,33 @@ static void unpack(void) } } -static void unpack_sideband(void) +static void unpack_sideband(int argc, const char **argv) { struct packet_reader reader; - packet_reader_init(&reader, 0, NULL, 0, - PACKET_READ_GENTLE_ON_EOF | - PACKET_READ_CHOMP_NEWLINE); + int options = PACKET_READ_GENTLE_ON_EOF; + int chomp_newline = 1; + int reader_use_sideband = 0; + const char *const unpack_sideband_usage[] = { + "test_tool unpack_sideband [options...]", NULL + }; + struct option cmd_options[] = { + OPT_BOOL(0, "reader-use-sideband", &reader_use_sideband, + "set use_sideband bit for packet reader (Default: off)"), + OPT_BOOL(0, "chomp-newline", &chomp_newline, + "chomp newline in packet (Default: on)"), + OPT_END() + }; + + argc = parse_options(argc, argv, "", cmd_options, unpack_sideband_usage, + 0); + if (argc > 0) + usage_msg_opt(_("too many arguments"), unpack_sideband_usage, + cmd_options); + + if (chomp_newline) + options |= PACKET_READ_CHOMP_NEWLINE; + packet_reader_init(&reader, 0, NULL, 0, options); + reader.use_sideband = reader_use_sideband; while (packet_reader_read(&reader) != PACKET_READ_EOF) { int band; @@ -79,6 +102,17 @@ static void unpack_sideband(void) case PACKET_READ_EOF: break; case PACKET_READ_NORMAL: + /* + * When the "use_sideband" field of the reader is turned + * on, sideband packets other than the payload have been + * parsed and consumed in packet_reader_read(), and only + * the payload arrives here. + */ + if (reader.use_sideband) { + write_or_die(1, reader.line, reader.pktlen - 1); + break; + } + band = reader.line[0] & 0xff; if (band < 1 || band > 2) continue; /* skip non-sideband packets */ @@ -97,15 +131,31 @@ static void unpack_sideband(void) static int send_split_sideband(void) { + const char *foo = "Foo.\n"; + const char *bar = "Bar.\n"; const char *part1 = "Hello,"; const char *primary = "\001primary: regular output\n"; const char *part2 = " world!\n"; + /* Each sideband message has a trailing newline character. */ + send_sideband(1, 2, foo, strlen(foo), LARGE_PACKET_MAX); + send_sideband(1, 2, bar, strlen(bar), LARGE_PACKET_MAX); + + /* + * One sideband message is divided into part1 and part2 + * by the primary message. + */ send_sideband(1, 2, part1, strlen(part1), LARGE_PACKET_MAX); packet_write(1, primary, strlen(primary)); send_sideband(1, 2, part2, strlen(part2), LARGE_PACKET_MAX); packet_response_end(1); + /* + * We use unpack_sideband() to consume packets. A flush packet + * is required to end parsing. + */ + packet_flush(1); + return 0; } @@ -126,7 +176,7 @@ int cmd__pkt_line(int argc, const char **argv) else if (!strcmp(argv[1], "unpack")) unpack(); else if (!strcmp(argv[1], "unpack-sideband")) - unpack_sideband(); + unpack_sideband(argc - 1, argv + 1); else if (!strcmp(argv[1], "send-split-sideband")) send_split_sideband(); else if (!strcmp(argv[1], "receive-sideband")) diff --git a/t/helper/test-prio-queue.c b/t/helper/test-prio-queue.c deleted file mode 100644 index f0bf255f5f..0000000000 --- a/t/helper/test-prio-queue.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "test-tool.h" -#include "prio-queue.h" - -static int intcmp(const void *va, const void *vb, void *data UNUSED) -{ - const int *a = va, *b = vb; - return *a - *b; -} - -static void show(int *v) -{ - if (!v) - printf("NULL\n"); - else - printf("%d\n", *v); - free(v); -} - -int cmd__prio_queue(int argc UNUSED, const char **argv) -{ - struct prio_queue pq = { intcmp }; - - while (*++argv) { - if (!strcmp(*argv, "get")) { - void *peek = prio_queue_peek(&pq); - void *get = prio_queue_get(&pq); - if (peek != get) - BUG("peek and get results do not match"); - show(get); - } else if (!strcmp(*argv, "dump")) { - void *peek; - void *get; - while ((peek = prio_queue_peek(&pq))) { - get = prio_queue_get(&pq); - if (peek != get) - BUG("peek and get results do not match"); - show(get); - } - } else if (!strcmp(*argv, "stack")) { - pq.compare = NULL; - } else { - int *v = xmalloc(sizeof(*v)); - *v = atoi(*argv); - prio_queue_put(&pq, v); - } - } - - clear_prio_queue(&pq); - - return 0; -} diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c index 3e173399a0..1e159a754d 100644 --- a/t/helper/test-reach.c +++ b/t/helper/test-reach.c @@ -1,11 +1,9 @@ #include "test-tool.h" #include "commit.h" #include "commit-reach.h" -#include "config.h" #include "gettext.h" #include "hex.h" #include "object-name.h" -#include "parse-options.h" #include "ref-filter.h" #include "setup.h" #include "string-list.h" diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index e9a444ddba..4acae41bb9 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -6,6 +6,7 @@ #include "pack-bitmap.h" #include "packfile.h" #include "setup.h" +#include "gettext.h" static int read_midx_file(const char *object_dir, int show_objects) { @@ -79,7 +80,7 @@ static int read_midx_checksum(const char *object_dir) static int read_midx_preferred_pack(const char *object_dir) { struct multi_pack_index *midx = NULL; - struct bitmap_index *bitmap = NULL; + uint32_t preferred_pack; setup_git_directory(); @@ -87,23 +88,45 @@ static int read_midx_preferred_pack(const char *object_dir) if (!midx) return 1; - bitmap = prepare_bitmap_git(the_repository); - if (!bitmap) + if (midx_preferred_pack(midx, &preferred_pack) < 0) { + warning(_("could not determine MIDX preferred pack")); return 1; - if (!bitmap_is_midx(bitmap)) { - free_bitmap_index(bitmap); + } + + printf("%s\n", midx->pack_names[preferred_pack]); + return 0; +} + +static int read_midx_bitmapped_packs(const char *object_dir) +{ + struct multi_pack_index *midx = NULL; + struct bitmapped_pack pack; + uint32_t i; + + setup_git_directory(); + + midx = load_multi_pack_index(object_dir, 1); + if (!midx) return 1; + + for (i = 0; i < midx->num_packs; i++) { + if (nth_bitmapped_pack(the_repository, midx, &pack, i) < 0) + return 1; + + printf("%s\n", pack_basename(pack.p)); + printf(" bitmap_pos: %"PRIuMAX"\n", (uintmax_t)pack.bitmap_pos); + printf(" bitmap_nr: %"PRIuMAX"\n", (uintmax_t)pack.bitmap_nr); } - printf("%s\n", midx->pack_names[midx_preferred_pack(bitmap)]); - free_bitmap_index(bitmap); + close_midx(midx); + return 0; } int cmd__read_midx(int argc, const char **argv) { if (!(argc == 2 || argc == 3)) - usage("read-midx [--show-objects|--checksum|--preferred-pack] <object-dir>"); + usage("read-midx [--show-objects|--checksum|--preferred-pack|--bitmap] <object-dir>"); if (!strcmp(argv[1], "--show-objects")) return read_midx_file(argv[2], 1); @@ -111,5 +134,7 @@ int cmd__read_midx(int argc, const char **argv) return read_midx_checksum(argv[2]); else if (!strcmp(argv[1], "--preferred-pack")) return read_midx_preferred_pack(argv[2]); + else if (!strcmp(argv[1], "--bitmap")) + return read_midx_bitmapped_packs(argv[2]); return read_midx_file(argv[1], 0); } diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 48552e6a9e..7a0f6cac53 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -221,15 +221,21 @@ static int cmd_verify_ref(struct ref_store *refs, const char **argv) return ret; } +static int each_reflog(const char *refname, void *cb_data UNUSED) +{ + printf("%s\n", refname); + return 0; +} + static int cmd_for_each_reflog(struct ref_store *refs, const char **argv UNUSED) { - return refs_for_each_reflog(refs, each_ref, NULL); + return refs_for_each_reflog(refs, each_reflog, NULL); } -static int each_reflog(struct object_id *old_oid, struct object_id *new_oid, - const char *committer, timestamp_t timestamp, - int tz, const char *msg, void *cb_data UNUSED) +static int each_reflog_ent(struct object_id *old_oid, struct object_id *new_oid, + const char *committer, timestamp_t timestamp, + int tz, const char *msg, void *cb_data UNUSED) { printf("%s %s %s %" PRItime " %+05d%s%s", oid_to_hex(old_oid), oid_to_hex(new_oid), committer, timestamp, tz, @@ -241,14 +247,14 @@ static int cmd_for_each_reflog_ent(struct ref_store *refs, const char **argv) { const char *refname = notnull(*argv++, "refname"); - return refs_for_each_reflog_ent(refs, refname, each_reflog, refs); + return refs_for_each_reflog_ent(refs, refname, each_reflog_ent, refs); } static int cmd_for_each_reflog_ent_reverse(struct ref_store *refs, const char **argv) { const char *refname = notnull(*argv++, "refname"); - return refs_for_each_reflog_ent_reverse(refs, refname, each_reflog, refs); + return refs_for_each_reflog_ent_reverse(refs, refname, each_reflog_ent, refs); } static int cmd_reflog_exists(struct ref_store *refs, const char **argv) @@ -298,16 +304,19 @@ static int cmd_update_ref(struct ref_store *refs, const char **argv) const char *new_sha1_buf = notnull(*argv++, "new-sha1"); const char *old_sha1_buf = notnull(*argv++, "old-sha1"); unsigned int flags = arg_flags(*argv++, "flags", transaction_flags); - struct object_id old_oid; + struct object_id old_oid, *old_oid_ptr = NULL; struct object_id new_oid; - if (get_oid_hex(old_sha1_buf, &old_oid)) - die("cannot parse %s as %s", old_sha1_buf, the_hash_algo->name); + if (*old_sha1_buf) { + if (get_oid_hex(old_sha1_buf, &old_oid)) + die("cannot parse %s as %s", old_sha1_buf, the_hash_algo->name); + old_oid_ptr = &old_oid; + } if (get_oid_hex(new_sha1_buf, &new_oid)) die("cannot parse %s as %s", new_sha1_buf, the_hash_algo->name); return refs_update_ref(refs, msg, refname, - &new_oid, &old_oid, + &new_oid, old_oid_ptr, flags, UPDATE_REFS_DIE_ON_ERR); } diff --git a/t/helper/test-regex.c b/t/helper/test-regex.c index bd871a735b..80042eafc2 100644 --- a/t/helper/test-regex.c +++ b/t/helper/test-regex.c @@ -30,7 +30,7 @@ static int test_regex_bug(void) if (regexec(&r, str, 1, m, 0)) die("no match of pattern '%s' to string '%s'", pat, str); - /* http://sourceware.org/bugzilla/show_bug.cgi?id=3957 */ + /* https://sourceware.org/bugzilla/show_bug.cgi?id=3957 */ if (m[0].rm_so == 3) /* matches '\n' when it should not */ die("regex bug confirmed: re-build git with NO_REGEX=1"); diff --git a/t/helper/test-repository.c b/t/helper/test-repository.c index 4cd8a952e5..0c7c5aa4dd 100644 --- a/t/helper/test-repository.c +++ b/t/helper/test-repository.c @@ -1,10 +1,8 @@ #include "test-tool.h" #include "commit-graph.h" #include "commit.h" -#include "config.h" #include "environment.h" #include "hex.h" -#include "object-store-ll.h" #include "object.h" #include "repository.h" #include "setup.h" diff --git a/t/helper/test-simple-ipc.c b/t/helper/test-simple-ipc.c index 941ae7e3bc..fb5927775d 100644 --- a/t/helper/test-simple-ipc.c +++ b/t/helper/test-simple-ipc.c @@ -4,7 +4,6 @@ #include "test-tool.h" #include "gettext.h" -#include "strbuf.h" #include "simple-ipc.h" #include "parse-options.h" #include "thread-utils.h" diff --git a/t/helper/test-submodule.c b/t/helper/test-submodule.c index 356e0a26c5..7197969a08 100644 --- a/t/helper/test-submodule.c +++ b/t/helper/test-submodule.c @@ -4,16 +4,24 @@ #include "remote.h" #include "repository.h" #include "setup.h" +#include "strbuf.h" #include "submodule-config.h" #include "submodule.h" #define TEST_TOOL_CHECK_NAME_USAGE \ - "test-tool submodule check-name <name>" + "test-tool submodule check-name" static const char *submodule_check_name_usage[] = { TEST_TOOL_CHECK_NAME_USAGE, NULL }; +#define TEST_TOOL_CHECK_URL_USAGE \ + "test-tool submodule check-url" +static const char *submodule_check_url_usage[] = { + TEST_TOOL_CHECK_URL_USAGE, + NULL +}; + #define TEST_TOOL_IS_ACTIVE_USAGE \ "test-tool submodule is-active <name>" static const char *submodule_is_active_usage[] = { @@ -30,31 +38,26 @@ static const char *submodule_resolve_relative_url_usage[] = { static const char *submodule_usage[] = { TEST_TOOL_CHECK_NAME_USAGE, + TEST_TOOL_CHECK_URL_USAGE, TEST_TOOL_IS_ACTIVE_USAGE, TEST_TOOL_RESOLVE_RELATIVE_URL_USAGE, NULL }; +typedef int (*check_fn_t)(const char *); + /* - * Exit non-zero if any of the submodule names given on the command line is - * invalid. If no names are given, filter stdin to print only valid names - * (which is primarily intended for testing). + * Apply 'check_fn' to each line of stdin, printing values that pass the check + * to stdout. */ -static int check_name(int argc, const char **argv) +static int check_submodule(check_fn_t check_fn) { - if (argc > 1) { - while (*++argv) { - if (check_submodule_name(*argv) < 0) - return 1; - } - } else { - struct strbuf buf = STRBUF_INIT; - while (strbuf_getline(&buf, stdin) != EOF) { - if (!check_submodule_name(buf.buf)) - printf("%s\n", buf.buf); - } - strbuf_release(&buf); + struct strbuf buf = STRBUF_INIT; + while (strbuf_getline(&buf, stdin) != EOF) { + if (!check_fn(buf.buf)) + printf("%s\n", buf.buf); } + strbuf_release(&buf); return 0; } @@ -68,7 +71,20 @@ static int cmd__submodule_check_name(int argc, const char **argv) if (argc) usage_with_options(submodule_check_name_usage, options); - return check_name(argc, argv); + return check_submodule(check_submodule_name); +} + +static int cmd__submodule_check_url(int argc, const char **argv) +{ + struct option options[] = { + OPT_END() + }; + argc = parse_options(argc, argv, "test-tools", options, + submodule_check_url_usage, 0); + if (argc) + usage_with_options(submodule_check_url_usage, options); + + return check_submodule(check_submodule_url); } static int cmd__submodule_is_active(int argc, const char **argv) @@ -194,6 +210,7 @@ static int cmd__submodule_config_writeable(int argc, const char **argv UNUSED) static struct test_cmd cmds[] = { { "check-name", cmd__submodule_check_name }, + { "check-url", cmd__submodule_check_url }, { "is-active", cmd__submodule_is_active }, { "resolve-relative-url", cmd__submodule_resolve_relative_url}, { "config-list", cmd__submodule_config_list }, diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 876cd2dc31..482a1e58a4 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -19,7 +19,6 @@ static struct test_cmd cmds[] = { { "config", cmd__config }, { "crontab", cmd__crontab }, { "csprng", cmd__csprng }, - { "ctype", cmd__ctype }, { "date", cmd__date }, { "delta", cmd__delta }, { "dir-iterator", cmd__dir_iterator }, @@ -30,7 +29,6 @@ static struct test_cmd cmds[] = { { "dump-untracked-cache", cmd__dump_untracked_cache }, { "env-helper", cmd__env_helper }, { "example-decorate", cmd__example_decorate }, - { "fast-rebase", cmd__fast_rebase }, { "find-pack", cmd__find_pack }, { "fsmonitor-client", cmd__fsmonitor_client }, { "genrandom", cmd__genrandom }, @@ -57,7 +55,6 @@ static struct test_cmd cmds[] = { { "path-utils", cmd__path_utils }, { "pcre2-config", cmd__pcre2_config }, { "pkt-line", cmd__pkt_line }, - { "prio-queue", cmd__prio_queue }, { "proc-receive", cmd__proc_receive }, { "progress", cmd__progress }, { "reach", cmd__reach }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 70dd4eba11..b1be7cfcf5 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -12,7 +12,6 @@ int cmd__chmtime(int argc, const char **argv); int cmd__config(int argc, const char **argv); int cmd__crontab(int argc, const char **argv); int cmd__csprng(int argc, const char **argv); -int cmd__ctype(int argc, const char **argv); int cmd__date(int argc, const char **argv); int cmd__delta(int argc, const char **argv); int cmd__dir_iterator(int argc, const char **argv); @@ -24,7 +23,6 @@ int cmd__dump_untracked_cache(int argc, const char **argv); int cmd__dump_reftable(int argc, const char **argv); int cmd__env_helper(int argc, const char **argv); int cmd__example_decorate(int argc, const char **argv); -int cmd__fast_rebase(int argc, const char **argv); int cmd__find_pack(int argc, const char **argv); int cmd__fsmonitor_client(int argc, const char **argv); int cmd__genrandom(int argc, const char **argv); @@ -50,7 +48,6 @@ int cmd__partial_clone(int argc, const char **argv); int cmd__path_utils(int argc, const char **argv); int cmd__pcre2_config(int argc, const char **argv); int cmd__pkt_line(int argc, const char **argv); -int cmd__prio_queue(int argc, const char **argv); int cmd__proc_receive(int argc, const char **argv); int cmd__progress(int argc, const char **argv); int cmd__reach(int argc, const char **argv); diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c index d5ca0046c8..1adac29a57 100644 --- a/t/helper/test-trace2.c +++ b/t/helper/test-trace2.c @@ -412,6 +412,56 @@ static int ut_201counter(int argc, const char **argv) return 0; } +static int ut_300redact_start(int argc, const char **argv) +{ + if (!argc) + die("expect <argv...>"); + + trace2_cmd_start(argv); + + return 0; +} + +static int ut_301redact_child_start(int argc, const char **argv) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + int k; + + if (!argc) + die("expect <argv...>"); + + for (k = 0; argv[k]; k++) + strvec_push(&cmd.args, argv[k]); + + trace2_child_start(&cmd); + + strvec_clear(&cmd.args); + + return 0; +} + +static int ut_302redact_exec(int argc, const char **argv) +{ + if (!argc) + die("expect <exe> <argv...>"); + + trace2_exec(argv[0], &argv[1]); + + return 0; +} + +static int ut_303redact_def_param(int argc, const char **argv) +{ + struct key_value_info kvi = KVI_INIT; + + if (argc < 2) + die("expect <key> <value>"); + + trace2_def_param(argv[0], argv[1], &kvi); + + return 0; +} + /* * Usage: * test-tool trace2 <ut_name_1> <ut_usage_1> @@ -438,6 +488,11 @@ static struct unit_test ut_table[] = { { ut_200counter, "200counter", "<v1> [<v2> [<v3> [...]]]" }, { ut_201counter, "201counter", "<v1> <v2> <threads>" }, + + { ut_300redact_start, "300redact_start", "<argv...>" }, + { ut_301redact_child_start, "301redact_child_start", "<argv...>" }, + { ut_302redact_exec, "302redact_exec", "<exe> <argv...>" }, + { ut_303redact_def_param, "303redact_def_param", "<key> <value>" }, }; /* clang-format on */ diff --git a/t/lib-credential.sh b/t/lib-credential.sh index 15fc9a31e2..44799c0d38 100644 --- a/t/lib-credential.sh +++ b/t/lib-credential.sh @@ -50,6 +50,7 @@ helper_test_clean() { reject $1 https example.com user-overwrite reject $1 https example.com user-erase1 reject $1 https example.com user-erase2 + reject $1 https victim.example.com user reject $1 http path.tld user reject $1 https timeout.tld user reject $1 https sso.tld diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh index 83b83c9abb..add11e88fc 100644 --- a/t/lib-gpg.sh +++ b/t/lib-gpg.sh @@ -13,7 +13,7 @@ test_lazy_prereq GPG ' gpg_version=$(gpg --version 2>&1) test $? != 127 || exit 1 - # As said here: http://www.gnupg.org/documentation/faqs.html#q6.19 + # As said here: https://web.archive.org/web/20130212022238/https://www.gnupg.org/faq/gnupg-faq.html#why-does-gnupg-1.0.6-bail-out-on-keyrings-used-with-1.0.7 # the gpg version 1.0.6 did not parse trust packets correctly, so for # that version, creation of signed tags using the generated key fails. case "$gpg_version" in diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 5fe3c8ab69..d83bafeab3 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -55,21 +55,31 @@ fi HTTPD_PARA="" -for DEFAULT_HTTPD_PATH in '/usr/sbin/httpd' '/usr/sbin/apache2' +for DEFAULT_HTTPD_PATH in '/usr/sbin/httpd' \ + '/usr/sbin/apache2' \ + "$(command -v httpd)" \ + "$(command -v apache2)" do - if test -x "$DEFAULT_HTTPD_PATH" + if test -n "$DEFAULT_HTTPD_PATH" && test -x "$DEFAULT_HTTPD_PATH" then break fi done +if test -x "$DEFAULT_HTTPD_PATH" +then + DETECTED_HTTPD_ROOT="$("$DEFAULT_HTTPD_PATH" -V 2>/dev/null | sed -n 's/^ -D HTTPD_ROOT="\(.*\)"$/\1/p')" +fi + for DEFAULT_HTTPD_MODULE_PATH in '/usr/libexec/apache2' \ '/usr/lib/apache2/modules' \ '/usr/lib64/httpd/modules' \ '/usr/lib/httpd/modules' \ - '/usr/libexec/httpd' + '/usr/libexec/httpd' \ + '/usr/lib/apache2' \ + "${DETECTED_HTTPD_ROOT:+${DETECTED_HTTPD_ROOT}/modules}" do - if test -d "$DEFAULT_HTTPD_MODULE_PATH" + if test -n "$DEFAULT_HTTPD_MODULE_PATH" && test -d "$DEFAULT_HTTPD_MODULE_PATH" then break fi @@ -127,6 +137,20 @@ else "Could not identify web server at '$LIB_HTTPD_PATH'" fi +if test -n "$LIB_HTTPD_DAV" && test -f /etc/os-release +then + case "$(grep "^ID=" /etc/os-release | cut -d= -f2-)" in + alpine) + # The WebDAV module in Alpine Linux is broken at least up to + # Alpine v3.16 as the default DBM driver is missing. + # + # https://gitlab.alpinelinux.org/alpine/aports/-/issues/13112 + test_skip_or_die GIT_TEST_HTTPD \ + "Apache WebDAV module does not have default DBM backend driver" + ;; + esac +fi + install_script () { write_script "$HTTPD_ROOT_PATH/$1" <"$TEST_PATH/$1" } diff --git a/t/lib-httpd/passwd b/t/lib-httpd/passwd index 99a34d6487..d9c122f348 100644 --- a/t/lib-httpd/passwd +++ b/t/lib-httpd/passwd @@ -1 +1 @@ -user@host:xb4E8pqD81KQs +user@host:$apr1$LGPmCZWj$9vxEwj5Z5GzQLBMxp3mCx1 diff --git a/t/lib-httpd/proxy-passwd b/t/lib-httpd/proxy-passwd index 77c25138e0..2ad7705d9a 100644 --- a/t/lib-httpd/proxy-passwd +++ b/t/lib-httpd/proxy-passwd @@ -1 +1 @@ -proxuser:2x7tAukjAED5M +proxuser:$apr1$RxS6MLkD$DYsqQdflheq4GPNxzJpx5. diff --git a/t/perf/p5332-multi-pack-reuse.sh b/t/perf/p5332-multi-pack-reuse.sh new file mode 100755 index 0000000000..5c6c575d62 --- /dev/null +++ b/t/perf/p5332-multi-pack-reuse.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +test_description='tests pack performance with multi-pack reuse' + +. ./perf-lib.sh +. "${TEST_DIRECTORY}/perf/lib-pack.sh" + +packdir=.git/objects/pack + +test_perf_large_repo + +find_pack () { + for idx in $packdir/pack-*.idx + do + if git show-index <$idx | grep -q "$1" + then + basename $idx + fi || return 1 + done +} + +repack_into_n_chunks () { + git repack -adk && + + test "$1" -eq 1 && return || + + find $packdir -type f | sort >packs.before && + + # partition the repository into $1 chunks of consecutive commits, and + # then create $1 packs with the objects reachable from each chunk + # (excluding any objects reachable from the previous chunks) + sz="$(($(git rev-list --count --all) / $1))" + for rev in $(git rev-list --all | awk "NR % $sz == 0" | tac) + do + pack="$(echo "$rev" | git pack-objects --revs \ + --honor-pack-keep --delta-base-offset $packdir/pack)" && + touch $packdir/pack-$pack.keep || return 1 + done + + # grab any remaining objects not packed by the previous step(s) + git pack-objects --revs --all --honor-pack-keep --delta-base-offset \ + $packdir/pack && + + find $packdir -type f | sort >packs.after && + + # and install the whole thing + for f in $(comm -12 packs.before packs.after) + do + rm -f "$f" || return 1 + done + rm -fr $packdir/*.keep +} + +for nr_packs in 1 10 100 +do + test_expect_success "create $nr_packs-pack scenario" ' + repack_into_n_chunks $nr_packs + ' + + test_expect_success "setup bitmaps for $nr_packs-pack scenario" ' + find $packdir -type f -name "*.idx" | sed -e "s/.*\/\(.*\)$/+\1/g" | + git multi-pack-index write --stdin-packs --bitmap \ + --preferred-pack="$(find_pack $(git rev-parse HEAD))" + ' + + for reuse in single multi + do + test_perf "clone for $nr_packs-pack scenario ($reuse-pack reuse)" " + git for-each-ref --format='%(objectname)' refs/heads refs/tags >in && + git -c pack.allowPackReuse=$reuse pack-objects \ + --revs --delta-base-offset --use-bitmap-index \ + --stdout <in >result + " + + test_size "clone size for $nr_packs-pack scenario ($reuse-pack reuse)" ' + wc -c <result + ' + done +done + +test_done diff --git a/t/perf/p6300-for-each-ref.sh b/t/perf/p6300-for-each-ref.sh new file mode 100755 index 0000000000..fa7289c752 --- /dev/null +++ b/t/perf/p6300-for-each-ref.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +test_description='performance of for-each-ref' +. ./perf-lib.sh + +test_perf_fresh_repo + +ref_count_per_type=10000 +test_iteration_count=10 + +test_expect_success "setup" ' + test_commit_bulk $(( 1 + $ref_count_per_type )) && + + # Create refs + test_seq $ref_count_per_type | + sed "s,.*,update refs/heads/branch_& HEAD~&\nupdate refs/custom/special_& HEAD~&," | + git update-ref --stdin && + + # Create annotated tags + for i in $(test_seq $ref_count_per_type) + do + # Base tags + echo "tag tag_$i" && + echo "mark :$i" && + echo "from HEAD~$i" && + printf "tagger %s <%s> %s\n" \ + "$GIT_COMMITTER_NAME" \ + "$GIT_COMMITTER_EMAIL" \ + "$GIT_COMMITTER_DATE" && + echo "data <<EOF" && + echo "tag $i" && + echo "EOF" && + + # Nested tags + echo "tag nested_$i" && + echo "from :$i" && + printf "tagger %s <%s> %s\n" \ + "$GIT_COMMITTER_NAME" \ + "$GIT_COMMITTER_EMAIL" \ + "$GIT_COMMITTER_DATE" && + echo "data <<EOF" && + echo "nested tag $i" && + echo "EOF" || return 1 + done | git fast-import +' + +test_for_each_ref () { + title="for-each-ref" + if test $# -gt 0; then + title="$title ($1)" + shift + fi + args="$@" + + test_perf "$title" " + for i in \$(test_seq $test_iteration_count); do + git for-each-ref $args >/dev/null + done + " +} + +run_tests () { + test_for_each_ref "$1" + test_for_each_ref "$1, no sort" --no-sort + test_for_each_ref "$1, --count=1" --count=1 + test_for_each_ref "$1, --count=1, no sort" --no-sort --count=1 + test_for_each_ref "$1, tags" refs/tags/ + test_for_each_ref "$1, tags, no sort" --no-sort refs/tags/ + test_for_each_ref "$1, tags, dereferenced" '--format="%(refname) %(objectname) %(*objectname)"' refs/tags/ + test_for_each_ref "$1, tags, dereferenced, no sort" --no-sort '--format="%(refname) %(objectname) %(*objectname)"' refs/tags/ + + test_perf "for-each-ref ($1, tags) + cat-file --batch-check (dereferenced)" " + for i in \$(test_seq $test_iteration_count); do + git for-each-ref --format='%(objectname)^{} %(refname) %(objectname)' refs/tags/ | \ + git cat-file --batch-check='%(objectname) %(rest)' >/dev/null + done + " +} + +run_tests "loose" + +test_expect_success 'pack refs' ' + git pack-refs --all +' +run_tests "packed" + +test_done diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index e7786775a9..ab0c763411 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -15,7 +15,7 @@ # 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/ . +# along with this program. If not, see https://www.gnu.org/licenses/ . # These variables must be set before the inclusion of test-lib.sh below, # because it will change our working directory. @@ -31,7 +31,7 @@ unset GIT_CONFIG_NOSYSTEM GIT_CONFIG_SYSTEM="$TEST_DIRECTORY/perf/config" export GIT_CONFIG_SYSTEM -if test -n "$GIT_TEST_INSTALLED" -a -z "$PERF_SET_GIT_TEST_INSTALLED" +if test -n "$GIT_TEST_INSTALLED" && test -z "$PERF_SET_GIT_TEST_INSTALLED" then error "Do not use GIT_TEST_INSTALLED with the perf tests. diff --git a/t/perf/run b/t/perf/run index 34115edec3..486ead2198 100755 --- a/t/perf/run +++ b/t/perf/run @@ -91,10 +91,10 @@ set_git_test_installed () { run_dirs_helper () { mydir=${1%/} shift - while test $# -gt 0 -a "$1" != -- -a ! -f "$1"; do + while test $# -gt 0 && test "$1" != -- && test ! -f "$1"; do shift done - if test $# -gt 0 -a "$1" = --; then + if test $# -gt 0 && test "$1" = --; then shift fi @@ -124,7 +124,7 @@ run_dirs_helper () { } run_dirs () { - while test $# -gt 0 -a "$1" != -- -a ! -f "$1"; do + while test $# -gt 0 && test "$1" != -- && test ! -f "$1"; do run_dirs_helper "$@" shift done @@ -180,7 +180,8 @@ run_subsection () { GIT_PERF_AGGREGATING_LATER=t export GIT_PERF_AGGREGATING_LATER - if test $# = 0 -o "$1" = -- -o -f "$1"; then + if test $# = 0 || test "$1" = -- || test -f "$1" + then set -- . "$@" fi diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 2b78e3be47..b131d665db 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -532,6 +532,76 @@ test_expect_success 'init rejects attempts to initialize with different hash' ' test_must_fail git -C sha256 init --object-format=sha1 ' +test_expect_success DEFAULT_REPO_FORMAT 'extensions.refStorage is not allowed with repo version 0' ' + test_when_finished "rm -rf refstorage" && + git init refstorage && + git -C refstorage config extensions.refStorage files && + test_must_fail git -C refstorage rev-parse 2>err && + grep "repo version is 0, but v1-only extension found" err +' + +test_expect_success DEFAULT_REPO_FORMAT 'extensions.refStorage with files backend' ' + test_when_finished "rm -rf refstorage" && + git init refstorage && + git -C refstorage config core.repositoryformatversion 1 && + git -C refstorage config extensions.refStorage files && + test_commit -C refstorage A && + git -C refstorage rev-parse --verify HEAD +' + +test_expect_success DEFAULT_REPO_FORMAT 'extensions.refStorage with unknown backend' ' + test_when_finished "rm -rf refstorage" && + git init refstorage && + git -C refstorage config core.repositoryformatversion 1 && + git -C refstorage config extensions.refStorage garbage && + test_must_fail git -C refstorage rev-parse 2>err && + grep "invalid value for ${SQ}extensions.refstorage${SQ}: ${SQ}garbage${SQ}" err +' + +test_expect_success DEFAULT_REPO_FORMAT 'init with GIT_DEFAULT_REF_FORMAT=files' ' + test_when_finished "rm -rf refformat" && + GIT_DEFAULT_REF_FORMAT=files git init refformat && + echo 0 >expect && + git -C refformat config core.repositoryformatversion >actual && + test_cmp expect actual && + test_must_fail git -C refformat config extensions.refstorage +' + +test_expect_success 'init with GIT_DEFAULT_REF_FORMAT=garbage' ' + test_when_finished "rm -rf refformat" && + cat >expect <<-EOF && + fatal: unknown ref storage format ${SQ}garbage${SQ} + EOF + test_must_fail env GIT_DEFAULT_REF_FORMAT=garbage git init refformat 2>err && + test_cmp expect err +' + +test_expect_success 'init with --ref-format=files' ' + test_when_finished "rm -rf refformat" && + git init --ref-format=files refformat && + echo files >expect && + git -C refformat rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 're-init with same format' ' + test_when_finished "rm -rf refformat" && + git init --ref-format=files refformat && + git init --ref-format=files refformat && + echo files >expect && + git -C refformat rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'init with --ref-format=garbage' ' + test_when_finished "rm -rf refformat" && + cat >expect <<-EOF && + fatal: unknown ref storage format ${SQ}garbage${SQ} + EOF + test_must_fail git init --ref-format=garbage refformat 2>err && + test_cmp expect err +' + test_expect_success MINGW 'core.hidedotfiles = false' ' git config --global core.hidedotfiles false && rm -rf newdir && diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index aee2298f01..774b52c298 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -19,6 +19,20 @@ attr_check () { test_must_be_empty err } +attr_check_object_mode_basic () { + path="$1" && + expect="$2" && + check_opts="$3" && + git check-attr $check_opts builtin_objectmode -- "$path" >actual 2>err && + echo "$path: builtin_objectmode: $expect" >expect && + test_cmp expect actual +} + +attr_check_object_mode () { + attr_check_object_mode_basic "$@" && + test_must_be_empty err +} + attr_check_quote () { path="$1" quoted_path="$2" expect="$3" && @@ -558,4 +572,66 @@ test_expect_success EXPENSIVE 'large attributes file ignored in index' ' test_cmp expect err ' +test_expect_success 'builtin object mode attributes work (dir and regular paths)' ' + >normal && + attr_check_object_mode normal 100644 && + mkdir dir && + attr_check_object_mode dir 040000 +' + +test_expect_success POSIXPERM 'builtin object mode attributes work (executable)' ' + >exec && + chmod +x exec && + attr_check_object_mode exec 100755 +' + +test_expect_success SYMLINKS 'builtin object mode attributes work (symlinks)' ' + ln -s to_sym sym && + attr_check_object_mode sym 120000 +' + +test_expect_success 'native object mode attributes work with --cached' ' + >normal && + git add normal && + empty_blob=$(git rev-parse :normal) && + git update-index --index-info <<-EOF && + 100755 $empty_blob 0 exec + 120000 $empty_blob 0 symlink + EOF + attr_check_object_mode normal 100644 --cached && + attr_check_object_mode exec 100755 --cached && + attr_check_object_mode symlink 120000 --cached +' + +test_expect_success 'check object mode attributes work for submodules' ' + mkdir sub && + ( + cd sub && + git init && + mv .git .real && + echo "gitdir: .real" >.git && + test_commit first + ) && + attr_check_object_mode sub 160000 && + attr_check_object_mode sub unspecified --cached && + git add sub && + attr_check_object_mode sub 160000 --cached +' + +test_expect_success 'we do not allow user defined builtin_* attributes' ' + echo "foo* builtin_foo" >.gitattributes && + git add .gitattributes 2>actual && + echo "builtin_foo is not a valid attribute name: .gitattributes:1" >expect && + test_cmp expect actual +' + +test_expect_success 'user defined builtin_objectmode values are ignored' ' + echo "foo* builtin_objectmode=12345" >.gitattributes && + git add .gitattributes && + >foo_1 && + attr_check_object_mode_basic foo_1 100644 && + echo "builtin_objectmode is not a valid attribute name: .gitattributes:1" >expect && + test_cmp expect err +' + test_done diff --git a/t/t0009-prio-queue.sh b/t/t0009-prio-queue.sh deleted file mode 100755 index eea99107a4..0000000000 --- a/t/t0009-prio-queue.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh - -test_description='basic tests for priority queue implementation' - -TEST_PASSES_SANITIZE_LEAK=true -. ./test-lib.sh - -cat >expect <<'EOF' -1 -2 -3 -4 -5 -5 -6 -7 -8 -9 -10 -EOF -test_expect_success 'basic ordering' ' - test-tool prio-queue 2 6 3 10 9 5 7 4 5 8 1 dump >actual && - test_cmp expect actual -' - -cat >expect <<'EOF' -2 -3 -4 -1 -5 -6 -EOF -test_expect_success 'mixed put and get' ' - test-tool prio-queue 6 2 4 get 5 3 get get 1 dump >actual && - test_cmp expect actual -' - -cat >expect <<'EOF' -1 -2 -NULL -1 -2 -NULL -EOF -test_expect_success 'notice empty queue' ' - test-tool prio-queue 1 2 get get get 1 2 get get get >actual && - test_cmp expect actual -' - -cat >expect <<'EOF' -3 -2 -6 -4 -5 -1 -8 -EOF -test_expect_success 'stack order' ' - test-tool prio-queue stack 8 1 5 4 6 2 3 dump >actual && - test_cmp expect actual -' - -test_done diff --git a/t/t0018-advice.sh b/t/t0018-advice.sh index c13057a4ca..0dcfb760a2 100755 --- a/t/t0018-advice.sh +++ b/t/t0018-advice.sh @@ -17,7 +17,6 @@ test_expect_success 'advice should be printed when config variable is unset' ' test_expect_success 'advice should be printed when config variable is set to true' ' cat >expect <<-\EOF && hint: This is a piece of advice - hint: Disable this message with "git config advice.nestedTag false" EOF test_config advice.nestedTag true && test-tool advise "This is a piece of advice" 2>actual && diff --git a/t/t0024-crlf-archive.sh b/t/t0024-crlf-archive.sh index a34de56420..a7f4de4a43 100755 --- a/t/t0024-crlf-archive.sh +++ b/t/t0024-crlf-archive.sh @@ -9,7 +9,7 @@ test_expect_success setup ' git config core.autocrlf true && - printf "CRLF line ending\r\nAnd another\r\n" > sample && + printf "CRLF line ending\r\nAnd another\r\n" >sample && git add sample && test_tick && @@ -19,8 +19,9 @@ test_expect_success setup ' test_expect_success 'tar archive' ' - git archive --format=tar HEAD | - ( mkdir untarred && cd untarred && "$TAR" -xf - ) && + git archive --format=tar HEAD >test.tar && + mkdir untarred && + "$TAR" xf test.tar -C untarred && test_cmp sample untarred/sample @@ -30,7 +31,11 @@ test_expect_success UNZIP 'zip archive' ' git archive --format=zip HEAD >test.zip && - ( mkdir unzipped && cd unzipped && "$GIT_UNZIP" ../test.zip ) && + mkdir unzipped && + ( + cd unzipped && + "$GIT_UNZIP" ../test.zip + ) && test_cmp sample unzipped/sample diff --git a/t/t0035-safe-bare-repository.sh b/t/t0035-safe-bare-repository.sh index 038b8b788d..8048856379 100755 --- a/t/t0035-safe-bare-repository.sh +++ b/t/t0035-safe-bare-repository.sh @@ -78,4 +78,12 @@ test_expect_success 'no trace when GIT_DIR is explicitly provided' ' expect_accepted_explicit "$pwd/outer-repo/bare-repo" ' +test_expect_success 'no trace when "bare repository" is .git' ' + expect_accepted_implicit -C outer-repo/.git +' + +test_expect_success 'no trace when "bare repository" is a subdir of .git' ' + expect_accepted_implicit -C outer-repo/.git/objects +' + test_done diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 8fdef88b65..ec974867e4 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -376,7 +376,7 @@ test_expect_success 'OPT_CMDMODE() detects incompatibility (1)' ' test_must_be_empty output && test_grep "mode1" output.err && test_grep "mode2" output.err && - test_grep "is incompatible with" output.err + test_grep "cannot be used together" output.err ' test_expect_success 'OPT_CMDMODE() detects incompatibility (2)' ' @@ -384,7 +384,7 @@ test_expect_success 'OPT_CMDMODE() detects incompatibility (2)' ' test_must_be_empty output && test_grep "mode2" output.err && test_grep "set23" output.err && - test_grep "is incompatible with" output.err + test_grep "cannot be used together" output.err ' test_expect_success 'OPT_CMDMODE() detects incompatibility (3)' ' @@ -392,7 +392,7 @@ test_expect_success 'OPT_CMDMODE() detects incompatibility (3)' ' test_must_be_empty output && test_grep "mode2" output.err && test_grep "set23" output.err && - test_grep "is incompatible with" output.err + test_grep "cannot be used together" output.err ' test_expect_success 'OPT_CMDMODE() detects incompatibility (4)' ' @@ -401,7 +401,7 @@ test_expect_success 'OPT_CMDMODE() detects incompatibility (4)' ' test_must_be_empty output && test_grep "mode2" output.err && test_grep "mode34.3" output.err && - test_grep "is incompatible with" output.err + test_grep "cannot be used together" output.err ' test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' ' diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh index 487bc8d905..0ecec2ba71 100755 --- a/t/t0070-fundamental.sh +++ b/t/t0070-fundamental.sh @@ -9,10 +9,6 @@ Verify wrappers and compatibility functions. TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -test_expect_success 'character classes (isspace, isalpha etc.)' ' - test-tool ctype -' - test_expect_success 'mktemp to nonexistent directory prints filename' ' test_must_fail test-tool mktemp doesnotexist/testXXXXXX 2>err && grep "doesnotexist/test" err @@ -53,4 +49,62 @@ test_expect_success 'missing sideband designator is reported' ' test_grep "missing sideband" err ' +test_expect_success 'unpack-sideband: --no-chomp-newline' ' + test_when_finished "rm -f expect-out expect-err" && + test-tool pkt-line send-split-sideband >split-sideband && + test-tool pkt-line unpack-sideband \ + --no-chomp-newline <split-sideband >out 2>err && + cat >expect-out <<-EOF && + primary: regular output + EOF + cat >expect-err <<-EOF && + Foo. + Bar. + Hello, world! + EOF + test_cmp expect-out out && + test_cmp expect-err err +' + +test_expect_success 'unpack-sideband: --chomp-newline (default)' ' + test_when_finished "rm -f expect-out expect-err" && + test-tool pkt-line send-split-sideband >split-sideband && + test-tool pkt-line unpack-sideband \ + --chomp-newline <split-sideband >out 2>err && + printf "primary: regular output" >expect-out && + printf "Foo.Bar.Hello, world!" >expect-err && + test_cmp expect-out out && + test_cmp expect-err err +' + +test_expect_success 'unpack-sideband: packet_reader_read() consumes sideband, no chomp payload' ' + test_when_finished "rm -f expect-out expect-err" && + test-tool pkt-line send-split-sideband >split-sideband && + test-tool pkt-line unpack-sideband \ + --reader-use-sideband \ + --no-chomp-newline <split-sideband >out 2>err && + cat >expect-out <<-EOF && + primary: regular output + EOF + printf "remote: Foo. \n" >expect-err && + printf "remote: Bar. \n" >>expect-err && + printf "remote: Hello, world! \n" >>expect-err && + test_cmp expect-out out && + test_cmp expect-err err +' + +test_expect_success 'unpack-sideband: packet_reader_read() consumes sideband, chomp payload' ' + test_when_finished "rm -f expect-out expect-err" && + test-tool pkt-line send-split-sideband >split-sideband && + test-tool pkt-line unpack-sideband \ + --reader-use-sideband \ + --chomp-newline <split-sideband >out 2>err && + printf "primary: regular output" >expect-out && + printf "remote: Foo. \n" >expect-err && + printf "remote: Bar. \n" >>expect-err && + printf "remote: Hello, world! \n" >>expect-err && + test_cmp expect-out out && + test_cmp expect-err err +' + test_done diff --git a/t/t0080-unit-test-output.sh b/t/t0080-unit-test-output.sh new file mode 100755 index 0000000000..6657c114a3 --- /dev/null +++ b/t/t0080-unit-test-output.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +test_description='Test the output of the unit test framework' + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh + +test_expect_success 'TAP output from unit tests' ' + cat >expect <<-EOF && + ok 1 - passing test + ok 2 - passing test and assertion return 1 + # check "1 == 2" failed at t/unit-tests/t-basic.c:76 + # left: 1 + # right: 2 + not ok 3 - failing test + ok 4 - failing test and assertion return 0 + not ok 5 - passing TEST_TODO() # TODO + ok 6 - passing TEST_TODO() returns 1 + # todo check ${SQ}check(x)${SQ} succeeded at t/unit-tests/t-basic.c:25 + not ok 7 - failing TEST_TODO() + ok 8 - failing TEST_TODO() returns 0 + # check "0" failed at t/unit-tests/t-basic.c:30 + # skipping test - missing prerequisite + # skipping check ${SQ}1${SQ} at t/unit-tests/t-basic.c:32 + ok 9 - test_skip() # SKIP + ok 10 - skipped test returns 1 + # skipping test - missing prerequisite + ok 11 - test_skip() inside TEST_TODO() # SKIP + ok 12 - test_skip() inside TEST_TODO() returns 1 + # check "0" failed at t/unit-tests/t-basic.c:48 + not ok 13 - TEST_TODO() after failing check + ok 14 - TEST_TODO() after failing check returns 0 + # check "0" failed at t/unit-tests/t-basic.c:56 + not ok 15 - failing check after TEST_TODO() + ok 16 - failing check after TEST_TODO() returns 0 + # check "!strcmp("\thello\\\\", "there\"\n")" failed at t/unit-tests/t-basic.c:61 + # left: "\011hello\\\\" + # right: "there\"\012" + # check "!strcmp("NULL", NULL)" failed at t/unit-tests/t-basic.c:62 + # left: "NULL" + # right: NULL + # check "${SQ}a${SQ} == ${SQ}\n${SQ}" failed at t/unit-tests/t-basic.c:63 + # left: ${SQ}a${SQ} + # right: ${SQ}\012${SQ} + # check "${SQ}\\\\${SQ} == ${SQ}\\${SQ}${SQ}" failed at t/unit-tests/t-basic.c:64 + # left: ${SQ}\\\\${SQ} + # right: ${SQ}\\${SQ}${SQ} + not ok 17 - messages from failing string and char comparison + # BUG: test has no checks at t/unit-tests/t-basic.c:91 + not ok 18 - test with no checks + ok 19 - test with no checks returns 0 + 1..19 + EOF + + ! "$GIT_BUILD_DIR"/t/unit-tests/bin/t-basic >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh index 8798feefe3..fca39048fe 100755 --- a/t/t0091-bugreport.sh +++ b/t/t0091-bugreport.sh @@ -39,9 +39,9 @@ test_expect_success 'sanity check "System Info" section' ' sed -ne "/^\[System Info\]$/,/^$/p" <git-bugreport-format.txt >system && - # The beginning should match "git version --build-info" verbatim, + # The beginning should match "git version --build-options" verbatim, # but rather than checking bit-for-bit equality, just test some basics. - grep "git version [0-9]." system && + grep "git version " system && grep "shell-path: ." system && # After the version, there should be some more info. diff --git a/t/t0202/test.pl b/t/t0202/test.pl index 2cbf7b9590..47d96a2a13 100755 --- a/t/t0202/test.pl +++ b/t/t0202/test.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -use 5.008; +use 5.008001; use lib (split(/:/, $ENV{GITPERLLIB})); use strict; use warnings; diff --git a/t/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh index 80e76a4695..c312657a12 100755 --- a/t/t0210-trace2-normal.sh +++ b/t/t0210-trace2-normal.sh @@ -2,7 +2,7 @@ test_description='test trace2 facility (normal target)' -TEST_PASSES_SANITIZE_LEAK=true +TEST_PASSES_SANITIZE_LEAK=false . ./test-lib.sh # Turn off any inherited trace2 settings for this test. @@ -283,4 +283,22 @@ test_expect_success 'using global config with include' ' test_cmp expect actual ' +test_expect_success 'unsafe URLs are redacted by default' ' + test_when_finished \ + "rm -r trace.normal unredacted.normal clone clone2" && + + test_config_global \ + "url.$(pwd).insteadOf" https://user:pwd@example.com/ && + test_config_global trace2.configParams "core.*,remote.*.url" && + + GIT_TRACE2="$(pwd)/trace.normal" \ + git clone https://user:pwd@example.com/ clone && + ! grep user:pwd trace.normal && + + GIT_TRACE2_REDACT=0 GIT_TRACE2="$(pwd)/unredacted.normal" \ + git clone https://user:pwd@example.com/ clone2 && + grep "start .* clone https://user:pwd@example.com" unredacted.normal && + grep "remote.origin.url=https://user:pwd@example.com" unredacted.normal +' + test_done diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh index cfba686132..290b6eaaab 100755 --- a/t/t0211-trace2-perf.sh +++ b/t/t0211-trace2-perf.sh @@ -2,7 +2,7 @@ test_description='test trace2 facility (perf target)' -TEST_PASSES_SANITIZE_LEAK=true +TEST_PASSES_SANITIZE_LEAK=false . ./test-lib.sh # Turn off any inherited trace2 settings for this test. @@ -268,4 +268,23 @@ test_expect_success PTHREADS 'global counter test/test2' ' have_counter_event "main" "counter" "test" "test2" 60 actual ' +test_expect_success 'unsafe URLs are redacted by default' ' + test_when_finished \ + "rm -r actual trace.perf unredacted.perf clone clone2" && + + test_config_global \ + "url.$(pwd).insteadOf" https://user:pwd@example.com/ && + test_config_global trace2.configParams "core.*,remote.*.url" && + + GIT_TRACE2_PERF="$(pwd)/trace.perf" \ + git clone https://user:pwd@example.com/ clone && + ! grep user:pwd trace.perf && + + GIT_TRACE2_REDACT=0 GIT_TRACE2_PERF="$(pwd)/unredacted.perf" \ + git clone https://user:pwd@example.com/ clone2 && + perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <unredacted.perf >actual && + grep "d0|main|start|.* clone https://user:pwd@example.com" actual && + grep "d0|main|def_param|.*|remote.origin.url:https://user:pwd@example.com" actual +' + test_done diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh index 6d3374ff77..147643d582 100755 --- a/t/t0212-trace2-event.sh +++ b/t/t0212-trace2-event.sh @@ -323,4 +323,44 @@ test_expect_success 'discard traces when there are too many files' ' head -n2 trace_target_dir/git-trace2-discard | tail -n1 | grep \"event\":\"too_many_files\" ' +# In the following "...redact..." tests, skip testing the GIT_TRACE2_REDACT=0 +# case because we would need to exactly model the full JSON event stream like +# we did in the basic tests above and I do not think it is worth it. + +test_expect_success 'unsafe URLs are redacted by default in cmd_start events' ' + test_when_finished \ + "rm -r trace.event" && + + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + test-tool trace2 300redact_start git clone https://user:pwd@example.com/ clone2 && + ! grep user:pwd trace.event +' + +test_expect_success 'unsafe URLs are redacted by default in child_start events' ' + test_when_finished \ + "rm -r trace.event" && + + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + test-tool trace2 301redact_child_start git clone https://user:pwd@example.com/ clone2 && + ! grep user:pwd trace.event +' + +test_expect_success 'unsafe URLs are redacted by default in exec events' ' + test_when_finished \ + "rm -r trace.event" && + + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + test-tool trace2 302redact_exec git clone https://user:pwd@example.com/ clone2 && + ! grep user:pwd trace.event +' + +test_expect_success 'unsafe URLs are redacted by default in def_param events' ' + test_when_finished \ + "rm -r trace.event" && + + GIT_TRACE2_EVENT="$(pwd)/trace.event" \ + test-tool trace2 303redact_def_param url https://user:pwd@example.com/ && + ! grep user:pwd trace.event +' + test_done diff --git a/t/t0303-credential-external.sh b/t/t0303-credential-external.sh index 095574bfc6..72ae405c3e 100755 --- a/t/t0303-credential-external.sh +++ b/t/t0303-credential-external.sh @@ -32,9 +32,24 @@ commands. . ./test-lib.sh . "$TEST_DIRECTORY"/lib-credential.sh +# If we're not given a specific external helper to run against, +# there isn't much to test. But we can still run through our +# battery of tests with a fake helper and check that the +# test themselves are self-consistent and clean up after +# themselves. +# +# We'll use the "store" helper, since we can easily inspect +# its state by looking at the on-disk file. But since it doesn't +# implement any caching or expiry logic, we'll cheat and override +# the "check" function to just report all results as OK. if test -z "$GIT_TEST_CREDENTIAL_HELPER"; then - skip_all="used to test external credential helpers" - test_done + GIT_TEST_CREDENTIAL_HELPER=store + GIT_TEST_CREDENTIAL_HELPER_TIMEOUT=store + check () { + test "$1" = "approve" || return 0 + git -c credential.helper=store credential approve + } + check_cleanup=t fi test -z "$GIT_TEST_CREDENTIAL_HELPER_SETUP" || @@ -59,4 +74,11 @@ fi # might be long-term system storage helper_test_clean "$GIT_TEST_CREDENTIAL_HELPER" +if test "$check_cleanup" = "t" +then + test_expect_success 'test cleanup removes everything' ' + test_must_be_empty "$HOME/.git-credentials" + ' +fi + test_done diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index 5b7bee888d..0f98b21be8 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -49,7 +49,7 @@ test_expect_success 'convert shallow clone to partial clone' ' test_cmp_config -C client 1 core.repositoryformatversion ' -test_expect_success SHA1 'convert to partial clone with noop extension' ' +test_expect_success DEFAULT_REPO_FORMAT 'convert to partial clone with noop extension' ' rm -fr server client && test_create_repo server && test_commit -C server my_commit 1 && @@ -60,7 +60,7 @@ test_expect_success SHA1 'convert to partial clone with noop extension' ' git -C client fetch --unshallow --filter="blob:none" ' -test_expect_success SHA1 'converting to partial clone fails with unrecognized extension' ' +test_expect_success DEFAULT_REPO_FORMAT 'converting to partial clone fails with unrecognized extension' ' rm -fr server client && test_create_repo server && test_commit -C server my_commit 1 && diff --git a/t/t0600-reffiles-backend.sh b/t/t0600-reffiles-backend.sh new file mode 100755 index 0000000000..64214340e7 --- /dev/null +++ b/t/t0600-reffiles-backend.sh @@ -0,0 +1,475 @@ +#!/bin/sh + +test_description='Test reffiles backend' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh + +if ! test_have_prereq REFFILES +then + skip_all='skipping reffiles specific tests' + test_done +fi + +test_expect_success 'setup' ' + git commit --allow-empty -m Initial && + C=$(git rev-parse HEAD) && + git commit --allow-empty -m Second && + D=$(git rev-parse HEAD) && + git commit --allow-empty -m Third && + E=$(git rev-parse HEAD) +' + +test_expect_success 'empty directory should not fool rev-parse' ' + prefix=refs/e-rev-parse && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + echo "$C" >expected && + git rev-parse $prefix/foo >actual && + test_cmp expected actual +' + +test_expect_success 'empty directory should not fool for-each-ref' ' + prefix=refs/e-for-each-ref && + git update-ref $prefix/foo $C && + git for-each-ref $prefix >expected && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + git for-each-ref $prefix >actual && + test_cmp expected actual +' + +test_expect_success 'empty directory should not fool create' ' + prefix=refs/e-create && + mkdir -p .git/$prefix/foo/bar/baz && + printf "create %s $C\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool verify' ' + prefix=refs/e-verify && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "verify %s $C\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool 1-arg update' ' + prefix=refs/e-update-1 && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "update %s $D\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool 2-arg update' ' + prefix=refs/e-update-2 && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "update %s $D $C\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool 0-arg delete' ' + prefix=refs/e-delete-0 && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "delete %s\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'empty directory should not fool 1-arg delete' ' + prefix=refs/e-delete-1 && + git update-ref $prefix/foo $C && + git pack-refs --all && + mkdir -p .git/$prefix/foo/bar/baz && + printf "delete %s $C\n" $prefix/foo | + git update-ref --stdin +' + +test_expect_success 'non-empty directory blocks create' ' + prefix=refs/ne-create && + mkdir -p .git/$prefix/foo/bar && + : >.git/$prefix/foo/bar/baz.lock && + test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/foo$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ + EOF + printf "%s\n" "update $prefix/foo $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ + EOF + printf "%s\n" "update $prefix/foo $D $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err +' + +test_expect_success 'broken reference blocks create' ' + prefix=refs/broken-create && + mkdir -p .git/$prefix && + echo "gobbledigook" >.git/$prefix/foo && + test_when_finished "rm -f .git/$prefix/foo" && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken + EOF + printf "%s\n" "update $prefix/foo $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken + EOF + printf "%s\n" "update $prefix/foo $D $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err +' + +test_expect_success 'non-empty directory blocks indirect create' ' + prefix=refs/ne-indirect-create && + git symbolic-ref $prefix/symref $prefix/foo && + mkdir -p .git/$prefix/foo/bar && + : >.git/$prefix/foo/bar/baz.lock && + test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/symref$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ + EOF + printf "%s\n" "update $prefix/symref $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ + EOF + printf "%s\n" "update $prefix/symref $D $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err +' + +test_expect_success 'broken reference blocks indirect create' ' + prefix=refs/broken-indirect-create && + git symbolic-ref $prefix/symref $prefix/foo && + echo "gobbledigook" >.git/$prefix/foo && + test_when_finished "rm -f .git/$prefix/foo" && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken + EOF + printf "%s\n" "update $prefix/symref $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err && + cat >expected <<-EOF && + fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken + EOF + printf "%s\n" "update $prefix/symref $D $C" | + test_must_fail git update-ref --stdin 2>output.err && + test_cmp expected output.err +' + +test_expect_success 'no bogus intermediate values during delete' ' + prefix=refs/slow-transaction && + # Set up a reference with differing loose and packed versions: + git update-ref $prefix/foo $C && + git pack-refs --all && + git update-ref $prefix/foo $D && + # Now try to update the reference, but hold the `packed-refs` lock + # for a while to see what happens while the process is blocked: + : >.git/packed-refs.lock && + test_when_finished "rm -f .git/packed-refs.lock" && + { + # Note: the following command is intentionally run in the + # background. We increase the timeout so that `update-ref` + # attempts to acquire the `packed-refs` lock for much longer + # than it takes for us to do the check then delete it: + git -c core.packedrefstimeout=30000 update-ref -d $prefix/foo & + } && + pid2=$! && + # Give update-ref plenty of time to get to the point where it tries + # to lock packed-refs: + sleep 1 && + # Make sure that update-ref did not complete despite the lock: + kill -0 $pid2 && + # Verify that the reference still has its old value: + sha1=$(git rev-parse --verify --quiet $prefix/foo || echo undefined) && + case "$sha1" in + $D) + # This is what we hope for; it means that nothing + # user-visible has changed yet. + : ;; + undefined) + # This is not correct; it means the deletion has happened + # already even though update-ref should not have been + # able to acquire the lock yet. + echo "$prefix/foo deleted prematurely" && + break + ;; + $C) + # This value should never be seen. Probably the loose + # reference has been deleted but the packed reference + # is still there: + echo "$prefix/foo incorrectly observed to be C" && + break + ;; + *) + # WTF? + echo "unexpected value observed for $prefix/foo: $sha1" && + break + ;; + esac >out && + rm -f .git/packed-refs.lock && + wait $pid2 && + test_must_be_empty out && + test_must_fail git rev-parse --verify --quiet $prefix/foo +' + +test_expect_success 'delete fails cleanly if packed-refs file is locked' ' + prefix=refs/locked-packed-refs && + # Set up a reference with differing loose and packed versions: + git update-ref $prefix/foo $C && + git pack-refs --all && + git update-ref $prefix/foo $D && + git for-each-ref $prefix >unchanged && + # Now try to delete it while the `packed-refs` lock is held: + : >.git/packed-refs.lock && + test_when_finished "rm -f .git/packed-refs.lock" && + test_must_fail git update-ref -d $prefix/foo >out 2>err && + git for-each-ref $prefix >actual && + test_grep "Unable to create $SQ.*packed-refs.lock$SQ: " err && + test_cmp unchanged actual +' + +test_expect_success 'delete fails cleanly if packed-refs.new write fails' ' + # Setup and expectations are similar to the test above. + prefix=refs/failed-packed-refs && + git update-ref $prefix/foo $C && + git pack-refs --all && + git update-ref $prefix/foo $D && + git for-each-ref $prefix >unchanged && + # This should not happen in practice, but it is an easy way to get a + # reliable error (we open with create_tempfile(), which uses O_EXCL). + : >.git/packed-refs.new && + test_when_finished "rm -f .git/packed-refs.new" && + test_must_fail git update-ref -d $prefix/foo && + git for-each-ref $prefix >actual && + test_cmp unchanged actual +' + +RWT="test-tool ref-store worktree:wt" +RMAIN="test-tool ref-store worktree:main" + +test_expect_success 'setup worktree' ' + test_commit first && + git worktree add -b wt-main wt && + ( + cd wt && + test_commit second + ) +' + +# Some refs (refs/bisect/*, pseudorefs) are kept per worktree, so they should +# only appear in the for-each-reflog output if it is called from the correct +# worktree, which is exercised in this test. This test is poorly written for +# mulitple reasons: 1) it creates invalidly formatted log entres. 2) it uses +# direct FS access for creating the reflogs. 3) PSEUDO-WT and refs/bisect/random +# do not create reflogs by default, so it is not testing a realistic scenario. +test_expect_success 'for_each_reflog()' ' + echo $ZERO_OID >.git/logs/PSEUDO_MAIN_HEAD && + mkdir -p .git/logs/refs/bisect && + echo $ZERO_OID >.git/logs/refs/bisect/random && + + echo $ZERO_OID >.git/worktrees/wt/logs/PSEUDO_WT_HEAD && + mkdir -p .git/worktrees/wt/logs/refs/bisect && + echo $ZERO_OID >.git/worktrees/wt/logs/refs/bisect/wt-random && + + $RWT for-each-reflog >actual && + cat >expected <<-\EOF && + HEAD + PSEUDO_WT_HEAD + refs/bisect/wt-random + refs/heads/main + refs/heads/wt-main + EOF + test_cmp expected actual && + + $RMAIN for-each-reflog >actual && + cat >expected <<-\EOF && + HEAD + PSEUDO_MAIN_HEAD + refs/bisect/random + refs/heads/main + refs/heads/wt-main + EOF + test_cmp expected actual +' + +# Triggering the bug detected by this test requires a newline to fall +# exactly BUFSIZ-1 bytes from the end of the file. We don't know +# what that value is, since it's platform dependent. However, if +# we choose some value N, we also catch any D which divides N evenly +# (since we will read backwards in chunks of D). So we choose 8K, +# which catches glibc (with an 8K BUFSIZ) and *BSD (1K). +# +# Each line is 114 characters, so we need 75 to still have a few before the +# last 8K. The 89-character padding on the final entry lines up our +# newline exactly. +test_expect_success SHA1 'parsing reverse reflogs at BUFSIZ boundaries' ' + git checkout -b reflogskip && + zf=$(test_oid zero_2) && + ident="abc <xyz> 0000000001 +0000" && + for i in $(test_seq 1 75); do + printf "$zf%02d $zf%02d %s\t" $i $(($i+1)) "$ident" && + if test $i = 75; then + for j in $(test_seq 1 89); do + printf X || return 1 + done + else + printf X + fi && + printf "\n" || return 1 + done >.git/logs/refs/heads/reflogskip && + git rev-parse reflogskip@{73} >actual && + echo ${zf}03 >expect && + test_cmp expect actual +' + +# This test takes a lock on an individual ref; this is not supported in +# reftable. +test_expect_success 'reflog expire operates on symref not referrent' ' + git branch --create-reflog the_symref && + git branch --create-reflog referrent && + git update-ref referrent HEAD && + git symbolic-ref refs/heads/the_symref refs/heads/referrent && + test_when_finished "rm -f .git/refs/heads/referrent.lock" && + touch .git/refs/heads/referrent.lock && + git reflog expire --expire=all the_symref +' + +test_expect_success 'empty reflog' ' + test_when_finished "rm -rf empty" && + git init empty && + test_commit -C empty A && + >empty/.git/logs/refs/heads/foo && + git -C empty reflog expire --all 2>err && + test_must_be_empty err +' + +test_expect_success SYMLINKS 'ref resolution not confused by broken symlinks' ' + ln -s does-not-exist .git/refs/heads/broken && + test_must_fail git rev-parse --verify broken +' + +test_expect_success 'log diagnoses bogus HEAD hash' ' + git init empty && + test_when_finished "rm -rf empty" && + echo 1234abcd >empty/.git/refs/heads/main && + test_must_fail git -C empty log 2>stderr && + test_grep broken stderr +' + +test_expect_success 'log diagnoses bogus HEAD symref' ' + git init empty && + test-tool -C empty ref-store main create-symref HEAD refs/heads/invalid.lock && + test_must_fail git -C empty log 2>stderr && + test_grep broken stderr && + test_must_fail git -C empty log --default totally-bogus 2>stderr && + test_grep broken stderr +' + +test_expect_success 'empty directory removal' ' + git branch d1/d2/r1 HEAD && + git branch d1/r2 HEAD && + test_path_is_file .git/refs/heads/d1/d2/r1 && + test_path_is_file .git/logs/refs/heads/d1/d2/r1 && + git branch -d d1/d2/r1 && + test_must_fail git show-ref --verify -q refs/heads/d1/d2 && + test_must_fail git show-ref --verify -q logs/refs/heads/d1/d2 && + test_path_is_file .git/refs/heads/d1/r2 && + test_path_is_file .git/logs/refs/heads/d1/r2 +' + +test_expect_success 'symref empty directory removal' ' + git branch e1/e2/r1 HEAD && + git branch e1/r2 HEAD && + git checkout e1/e2/r1 && + test_when_finished "git checkout main" && + test_path_is_file .git/refs/heads/e1/e2/r1 && + test_path_is_file .git/logs/refs/heads/e1/e2/r1 && + git update-ref -d HEAD && + test_must_fail git show-ref --verify -q refs/heads/e1/e2 && + test_must_fail git show-ref --verify -q logs/refs/heads/e1/e2 && + test_path_is_file .git/refs/heads/e1/r2 && + test_path_is_file .git/logs/refs/heads/e1/r2 && + test_path_is_file .git/logs/HEAD +' + +test_expect_success 'directory not created deleting packed ref' ' + git branch d1/d2/r1 HEAD && + git pack-refs --all && + test_path_is_missing .git/refs/heads/d1/d2 && + git update-ref -d refs/heads/d1/d2/r1 && + test_path_is_missing .git/refs/heads/d1/d2 && + test_path_is_missing .git/refs/heads/d1 +' + +test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for u is a symlink' ' + git branch --create-reflog u && + mv .git/logs/refs/heads/u real-u && + ln -s real-u .git/logs/refs/heads/u && + test_must_fail git branch -m u v +' + +test_expect_success SYMLINKS 'git branch -m with symlinked .git/refs' ' + test_when_finished "rm -rf subdir" && + git init --bare subdir && + + rm -rfv subdir/refs subdir/objects subdir/packed-refs && + ln -s ../.git/refs subdir/refs && + ln -s ../.git/objects subdir/objects && + ln -s ../.git/packed-refs subdir/packed-refs && + + git -C subdir rev-parse --absolute-git-dir >subdir.dir && + git rev-parse --absolute-git-dir >our.dir && + ! test_cmp subdir.dir our.dir && + + git -C subdir log && + git -C subdir branch rename-src && + git rev-parse rename-src >expect && + git -C subdir branch -m rename-src rename-dest && + git rev-parse rename-dest >actual && + test_cmp expect actual && + git branch -D rename-dest +' + +test_expect_success MINGW,SYMLINKS_WINDOWS 'rebase when .git/logs is a symlink' ' + git checkout main && + mv .git/logs actual_logs && + cmd //c "mklink /D .git\logs ..\actual_logs" && + git rebase -f HEAD^ && + test -L .git/logs && + rm .git/logs && + mv actual_logs .git/logs +' + +test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' ' + umask 077 && + git config core.sharedRepository group && + git reflog expire --all && + actual="$(ls -l .git/logs/refs/heads/main)" && + case "$actual" in + -rw-rw-*) + : happy + ;; + *) + echo Ooops, .git/logs/refs/heads/main is not 066x [$actual] + false + ;; + esac +' + +test_done diff --git a/t/t3210-pack-refs.sh b/t/t0601-reffiles-pack-refs.sh index 7f4e98db7d..c309d2bae8 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t0601-reffiles-pack-refs.sh @@ -15,6 +15,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +if ! test_have_prereq REFFILES +then + skip_all='skipping reffiles specific tests' + test_done +fi + test_expect_success 'enable reflogs' ' git config core.logallrefupdates true ' @@ -26,6 +32,14 @@ test_expect_success 'prepare a trivial repository' ' HEAD=$(git rev-parse --verify HEAD) ' +test_expect_success 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' ' + N=`find .git/refs -type f | wc -l` && + test "$N" != 0 && + test-tool ref-store main pack-refs PACK_REFS_PRUNE,PACK_REFS_ALL && + N=`find .git/refs -type f` && + test -z "$N" +' + SHA1= test_expect_success 'see if git show-ref works as expected' ' @@ -294,4 +308,54 @@ test_expect_success SYMLINKS 'pack symlinked packed-refs' ' test "$(test_readlink .git/packed-refs)" = "my-deviant-packed-refs" ' +# The 'packed-refs' file is stored directly in .git/. This means it is global +# to the repository, and can only contain refs that are shared across all +# worktrees. +test_expect_success 'refs/worktree must not be packed' ' + test_commit initial && + test_commit wt1 && + test_commit wt2 && + git worktree add wt1 wt1 && + git worktree add wt2 wt2 && + git checkout initial && + git update-ref refs/worktree/foo HEAD && + git -C wt1 update-ref refs/worktree/foo HEAD && + git -C wt2 update-ref refs/worktree/foo HEAD && + git pack-refs --all && + test_path_is_missing .git/refs/tags/wt1 && + test_path_is_file .git/refs/worktree/foo && + test_path_is_file .git/worktrees/wt1/refs/worktree/foo && + test_path_is_file .git/worktrees/wt2/refs/worktree/foo +' + +# we do not want to count on running pack-refs to +# actually pack it, as it is perfectly reasonable to +# skip processing a broken ref +test_expect_success 'create packed-refs file with broken ref' ' + test_tick && git commit --allow-empty -m one && + recoverable=$(git rev-parse HEAD) && + test_tick && git commit --allow-empty -m two && + missing=$(git rev-parse HEAD) && + rm -f .git/refs/heads/main && + cat >.git/packed-refs <<-EOF && + $missing refs/heads/main + $recoverable refs/heads/other + EOF + echo $missing >expect && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + +test_expect_success 'pack-refs does not silently delete broken packed ref' ' + git pack-refs --all --prune && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + +test_expect_success 'pack-refs does not drop broken refs during deletion' ' + git update-ref -d refs/heads/other && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + test_done diff --git a/t/t0610-reftable-basics.sh b/t/t0610-reftable-basics.sh new file mode 100755 index 0000000000..6a131e40b8 --- /dev/null +++ b/t/t0610-reftable-basics.sh @@ -0,0 +1,887 @@ +#!/bin/sh +# +# Copyright (c) 2020 Google LLC +# + +test_description='reftable basics' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh + +if ! test_have_prereq REFTABLE +then + skip_all='skipping reftable tests; set GIT_TEST_DEFAULT_REF_FORMAT=reftable' + test_done +fi + +INVALID_OID=$(test_oid 001) + +test_expect_success 'init: creates basic reftable structures' ' + test_when_finished "rm -rf repo" && + git init repo && + test_path_is_dir repo/.git/reftable && + test_path_is_file repo/.git/reftable/tables.list && + echo reftable >expect && + git -C repo rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'init: sha256 object format via environment variable' ' + test_when_finished "rm -rf repo" && + GIT_DEFAULT_HASH=sha256 git init repo && + cat >expect <<-EOF && + sha256 + reftable + EOF + git -C repo rev-parse --show-object-format --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'init: sha256 object format via option' ' + test_when_finished "rm -rf repo" && + git init --object-format=sha256 repo && + cat >expect <<-EOF && + sha256 + reftable + EOF + git -C repo rev-parse --show-object-format --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'init: reinitializing reftable backend succeeds' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo A && + + git -C repo for-each-ref >expect && + git init --ref-format=reftable repo && + git -C repo for-each-ref >actual && + test_cmp expect actual +' + +test_expect_success 'init: reinitializing files with reftable backend fails' ' + test_when_finished "rm -rf repo" && + git init --ref-format=files repo && + test_commit -C repo file && + + cp repo/.git/HEAD expect && + test_must_fail git init --ref-format=reftable repo && + test_cmp expect repo/.git/HEAD +' + +test_expect_success 'init: reinitializing reftable with files backend fails' ' + test_when_finished "rm -rf repo" && + git init --ref-format=reftable repo && + test_commit -C repo file && + + cp repo/.git/HEAD expect && + test_must_fail git init --ref-format=files repo && + test_cmp expect repo/.git/HEAD +' + +test_expect_perms () { + local perms="$1" + local file="$2" + local actual=$(ls -l "$file") && + + case "$actual" in + $perms*) + : happy + ;; + *) + echo "$(basename $2) is not $perms but $actual" + false + ;; + esac +} + +for umask in 002 022 +do + test_expect_success POSIXPERM 'init: honors core.sharedRepository' ' + test_when_finished "rm -rf repo" && + ( + umask $umask && + git init --shared=true repo && + test 1 = "$(git -C repo config core.sharedrepository)" + ) && + test_expect_perms "-rw-rw-r--" repo/.git/reftable/tables.list && + for table in repo/.git/reftable/*.ref + do + test_expect_perms "-rw-rw-r--" "$table" || + return 1 + done + ' +done + +test_expect_success 'clone: can clone reftable repository' ' + test_when_finished "rm -rf repo clone" && + git init repo && + test_commit -C repo message1 file1 && + + git clone repo cloned && + echo reftable >expect && + git -C cloned rev-parse --show-ref-format >actual && + test_cmp expect actual && + test_path_is_file cloned/file1 +' + +test_expect_success 'clone: can clone reffiles into reftable repository' ' + test_when_finished "rm -rf reffiles reftable" && + git init --ref-format=files reffiles && + test_commit -C reffiles A && + git clone --ref-format=reftable ./reffiles reftable && + + git -C reffiles rev-parse HEAD >expect && + git -C reftable rev-parse HEAD >actual && + test_cmp expect actual && + + git -C reftable rev-parse --show-ref-format >actual && + echo reftable >expect && + test_cmp expect actual && + + git -C reffiles rev-parse --show-ref-format >actual && + echo files >expect && + test_cmp expect actual +' + +test_expect_success 'clone: can clone reftable into reffiles repository' ' + test_when_finished "rm -rf reffiles reftable" && + git init --ref-format=reftable reftable && + test_commit -C reftable A && + git clone --ref-format=files ./reftable reffiles && + + git -C reftable rev-parse HEAD >expect && + git -C reffiles rev-parse HEAD >actual && + test_cmp expect actual && + + git -C reftable rev-parse --show-ref-format >actual && + echo reftable >expect && + test_cmp expect actual && + + git -C reffiles rev-parse --show-ref-format >actual && + echo files >expect && + test_cmp expect actual +' + +test_expect_success 'ref transaction: corrupted tables cause failure' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit file1 && + for f in .git/reftable/*.ref + do + : >"$f" || return 1 + done && + test_must_fail git update-ref refs/heads/main HEAD + ) +' + +test_expect_success 'ref transaction: corrupted tables.list cause failure' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit file1 && + echo garbage >.git/reftable/tables.list && + test_must_fail git update-ref refs/heads/main HEAD + ) +' + +test_expect_success 'ref transaction: refuses to write ref causing F/D conflict' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo file && + test_must_fail git -C repo update-ref refs/heads/main/forbidden +' + +test_expect_success 'ref transaction: deleting ref with invalid name fails' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo file && + test_must_fail git -C repo update-ref -d ../../my-private-file +' + +test_expect_success 'ref transaction: can skip object ID verification' ' + test_when_finished "rm -rf repo" && + git init repo && + test_must_fail test-tool -C repo ref-store main update-ref msg refs/heads/branch $INVALID_OID $ZERO_OID 0 && + test-tool -C repo ref-store main update-ref msg refs/heads/branch $INVALID_OID $ZERO_OID REF_SKIP_OID_VERIFICATION +' + +test_expect_success 'ref transaction: updating same ref multiple times fails' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo A && + cat >updates <<-EOF && + update refs/heads/main $A + update refs/heads/main $A + EOF + cat >expect <<-EOF && + fatal: multiple updates for ref ${SQ}refs/heads/main${SQ} not allowed + EOF + test_must_fail git -C repo update-ref --stdin <updates 2>err && + test_cmp expect err +' + +test_expect_success 'ref transaction: can delete symbolic self-reference with git-symbolic-ref(1)' ' + test_when_finished "rm -rf repo" && + git init repo && + git -C repo symbolic-ref refs/heads/self refs/heads/self && + git -C repo symbolic-ref -d refs/heads/self +' + +test_expect_success 'ref transaction: deleting symbolic self-reference without --no-deref fails' ' + test_when_finished "rm -rf repo" && + git init repo && + git -C repo symbolic-ref refs/heads/self refs/heads/self && + cat >expect <<-EOF && + error: multiple updates for ${SQ}refs/heads/self${SQ} (including one via symref ${SQ}refs/heads/self${SQ}) are not allowed + EOF + test_must_fail git -C repo update-ref -d refs/heads/self 2>err && + test_cmp expect err +' + +test_expect_success 'ref transaction: deleting symbolic self-reference with --no-deref succeeds' ' + test_when_finished "rm -rf repo" && + git init repo && + git -C repo symbolic-ref refs/heads/self refs/heads/self && + git -C repo update-ref -d --no-deref refs/heads/self +' + +test_expect_success 'ref transaction: creating symbolic ref fails with F/D conflict' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo A && + cat >expect <<-EOF && + error: unable to write symref for refs/heads: file/directory conflict + EOF + test_must_fail git -C repo symbolic-ref refs/heads refs/heads/foo 2>err && + test_cmp expect err +' + +test_expect_success 'ref transaction: ref deletion' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit file && + HEAD_OID=$(git show-ref -s --verify HEAD) && + cat >expect <<-EOF && + $HEAD_OID refs/heads/main + $HEAD_OID refs/tags/file + EOF + git show-ref >actual && + test_cmp expect actual && + + test_must_fail git update-ref -d refs/tags/file $INVALID_OID && + git show-ref >actual && + test_cmp expect actual && + + git update-ref -d refs/tags/file $HEAD_OID && + echo "$HEAD_OID refs/heads/main" >expect && + git show-ref >actual && + test_cmp expect actual + ) +' + +test_expect_success 'ref transaction: writes cause auto-compaction' ' + test_when_finished "rm -rf repo" && + + git init repo && + test_line_count = 1 repo/.git/reftable/tables.list && + + test_commit -C repo --no-tag A && + test_line_count = 2 repo/.git/reftable/tables.list && + + test_commit -C repo --no-tag B && + test_line_count = 1 repo/.git/reftable/tables.list +' + +check_fsync_events () { + local trace="$1" && + shift && + + cat >expect && + sed -n \ + -e '/^{"event":"counter",.*"category":"fsync",/ { + s/.*"category":"fsync",//; + s/}$//; + p; + }' \ + <"$trace" >actual && + test_cmp expect actual +} + +test_expect_success 'ref transaction: writes are synced' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo initial && + + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ + GIT_TEST_FSYNC=true \ + git -C repo -c core.fsync=reference \ + -c core.fsyncMethod=fsync update-ref refs/heads/branch HEAD && + check_fsync_events trace2.txt <<-EOF + "name":"hardware-flush","count":2 + EOF +' + +test_expect_success 'pack-refs: compacts tables' ' + test_when_finished "rm -rf repo" && + git init repo && + + test_commit -C repo A && + ls -1 repo/.git/reftable >table-files && + test_line_count = 4 table-files && + test_line_count = 3 repo/.git/reftable/tables.list && + + git -C repo pack-refs && + ls -1 repo/.git/reftable >table-files && + test_line_count = 2 table-files && + test_line_count = 1 repo/.git/reftable/tables.list +' + +test_expect_success 'pack-refs: prunes stale tables' ' + test_when_finished "rm -rf repo" && + git init repo && + touch repo/.git/reftable/stale-table.ref && + git -C repo pack-refs && + test_path_is_missing repo/.git/reftable/stable-ref.ref +' + +test_expect_success 'pack-refs: does not prune non-table files' ' + test_when_finished "rm -rf repo" && + git init repo && + touch repo/.git/reftable/garbage && + git -C repo pack-refs && + test_path_is_file repo/.git/reftable/garbage +' + +for umask in 002 022 +do + test_expect_success POSIXPERM 'pack-refs: honors core.sharedRepository' ' + test_when_finished "rm -rf repo" && + ( + umask $umask && + git init --shared=true repo && + test_commit -C repo A && + test_line_count = 3 repo/.git/reftable/tables.list + ) && + git -C repo pack-refs && + test_expect_perms "-rw-rw-r--" repo/.git/reftable/tables.list && + for table in repo/.git/reftable/*.ref + do + test_expect_perms "-rw-rw-r--" "$table" || + return 1 + done + ' +done + +test_expect_success 'packed-refs: writes are synced' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo initial && + test_line_count = 2 table-files && + + : >trace2.txt && + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ + GIT_TEST_FSYNC=true \ + git -C repo -c core.fsync=reference \ + -c core.fsyncMethod=fsync pack-refs && + check_fsync_events trace2.txt <<-EOF + "name":"hardware-flush","count":2 + EOF +' + +test_expect_success 'ref iterator: bogus names are flagged' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit --no-tag file && + test-tool ref-store main update-ref msg "refs/heads/bogus..name" $(git rev-parse HEAD) $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + + cat >expect <<-EOF && + $ZERO_OID refs/heads/bogus..name 0xc + $(git rev-parse HEAD) refs/heads/main 0x0 + EOF + test-tool ref-store main for-each-ref "" >actual && + test_cmp expect actual + ) +' + +test_expect_success 'ref iterator: missing object IDs are not flagged' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test-tool ref-store main update-ref msg "refs/heads/broken-hash" $INVALID_OID $ZERO_OID REF_SKIP_OID_VERIFICATION && + + cat >expect <<-EOF && + $INVALID_OID refs/heads/broken-hash 0x0 + EOF + test-tool ref-store main for-each-ref "" >actual && + test_cmp expect actual + ) +' + +test_expect_success 'basic: commit and list refs' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo file && + test_write_lines refs/heads/main refs/tags/file >expect && + git -C repo for-each-ref --format="%(refname)" >actual && + test_cmp actual expect +' + +test_expect_success 'basic: can write large commit message' ' + test_when_finished "rm -rf repo" && + git init repo && + perl -e " + print \"this is a long commit message\" x 50000 + " >commit-msg && + git -C repo commit --allow-empty --file=../commit-msg +' + +test_expect_success 'basic: show-ref fails with empty repository' ' + test_when_finished "rm -rf repo" && + git init repo && + test_must_fail git -C repo show-ref >actual && + test_must_be_empty actual +' + +test_expect_success 'basic: can check out unborn branch' ' + test_when_finished "rm -rf repo" && + git init repo && + git -C repo checkout -b main +' + +test_expect_success 'basic: peeled tags are stored' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo file && + git -C repo tag -m "annotated tag" test_tag HEAD && + for ref in refs/heads/main refs/tags/file refs/tags/test_tag refs/tags/test_tag^{} + do + echo "$(git -C repo rev-parse "$ref") $ref" || return 1 + done >expect && + git -C repo show-ref -d >actual && + test_cmp expect actual +' + +test_expect_success 'basic: for-each-ref can print symrefs' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit file && + git branch && + git symbolic-ref refs/heads/sym refs/heads/main && + cat >expected <<-EOF && + refs/heads/main + EOF + git for-each-ref --format="%(symref)" refs/heads/sym >actual && + test_cmp expected actual + ) +' + +test_expect_success 'basic: notes' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + write_script fake_editor <<-\EOF && + echo "$MSG" >"$1" + echo "$MSG" >&2 + EOF + + test_commit 1st && + test_commit 2nd && + GIT_EDITOR=./fake_editor MSG=b4 git notes add && + GIT_EDITOR=./fake_editor MSG=b3 git notes edit && + echo b4 >expect && + git notes --ref commits@{1} show >actual && + test_cmp expect actual + ) +' + +test_expect_success 'basic: stash' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit file && + git stash list >expect && + test_line_count = 0 expect && + + echo hoi >>file.t && + git stash push -m stashed && + git stash list >expect && + test_line_count = 1 expect && + + git stash clear && + git stash list >expect && + test_line_count = 0 expect + ) +' + +test_expect_success 'basic: cherry-pick' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit message1 file1 && + test_commit message2 file2 && + git branch source && + git checkout HEAD^ && + test_commit message3 file3 && + git cherry-pick source && + test_path_is_file file2 + ) +' + +test_expect_success 'basic: rebase' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit message1 file1 && + test_commit message2 file2 && + git branch source && + git checkout HEAD^ && + test_commit message3 file3 && + git rebase source && + test_path_is_file file2 + ) +' + +test_expect_success 'reflog: can delete separate reflog entries' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + + test_commit file && + test_commit file2 && + test_commit file3 && + test_commit file4 && + git reflog >actual && + grep file3 actual && + + git reflog delete HEAD@{1} && + git reflog >actual && + ! grep file3 actual + ) +' + +test_expect_success 'reflog: can switch to previous branch' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit file1 && + git checkout -b branch1 && + test_commit file2 && + git checkout -b branch2 && + git switch - && + git rev-parse --symbolic-full-name HEAD >actual && + echo refs/heads/branch1 >expect && + test_cmp actual expect + ) +' + +test_expect_success 'reflog: copying branch writes reflog entry' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit file1 && + test_commit file2 && + oid=$(git rev-parse --short HEAD) && + git branch src && + cat >expect <<-EOF && + ${oid} dst@{0}: Branch: copied refs/heads/src to refs/heads/dst + ${oid} dst@{1}: branch: Created from main + EOF + git branch -c src dst && + git reflog dst >actual && + test_cmp expect actual + ) +' + +test_expect_success 'reflog: renaming branch writes reflog entry' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git symbolic-ref HEAD refs/heads/before && + test_commit file && + git show-ref >expected.refs && + sed s/before/after/g <expected.refs >expected && + git branch -M after && + git show-ref >actual && + test_cmp expected actual && + echo refs/heads/after >expected && + git symbolic-ref HEAD >actual && + test_cmp expected actual + ) +' + +test_expect_success 'reflog: can store empty logs' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + + test_must_fail test-tool ref-store main reflog-exists refs/heads/branch && + test-tool ref-store main create-reflog refs/heads/branch && + test-tool ref-store main reflog-exists refs/heads/branch && + test-tool ref-store main for-each-reflog-ent-reverse refs/heads/branch >actual && + test_must_be_empty actual + ) +' + +test_expect_success 'reflog: expiry empties reflog' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + + test_commit initial && + git checkout -b branch && + test_commit fileA && + test_commit fileB && + + cat >expect <<-EOF && + commit: fileB + commit: fileA + branch: Created from HEAD + EOF + git reflog show --format="%gs" refs/heads/branch >actual && + test_cmp expect actual && + + git reflog expire branch --expire=all && + git reflog show --format="%gs" refs/heads/branch >actual && + test_must_be_empty actual && + test-tool ref-store main reflog-exists refs/heads/branch + ) +' + +test_expect_success 'reflog: can be deleted' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + test-tool ref-store main reflog-exists refs/heads/main && + test-tool ref-store main delete-reflog refs/heads/main && + test_must_fail test-tool ref-store main reflog-exists refs/heads/main + ) +' + +test_expect_success 'reflog: garbage collection deletes reflog entries' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + + for count in $(test_seq 1 10) + do + test_commit "number $count" file.t $count number-$count || + return 1 + done && + git reflog refs/heads/main >actual && + test_line_count = 10 actual && + grep "commit (initial): number 1" actual && + grep "commit: number 10" actual && + + git gc && + git reflog refs/heads/main >actual && + test_line_count = 0 actual + ) +' + +test_expect_success 'reflog: updates via HEAD update HEAD reflog' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit main-one && + git checkout -b new-branch && + test_commit new-one && + test_commit new-two && + + echo new-one >expect && + git log -1 --format=%s HEAD@{1} >actual && + test_cmp expect actual + ) +' + +test_expect_success 'worktree: adding worktree creates separate stack' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo A && + + git -C repo worktree add ../worktree && + test_path_is_file repo/.git/worktrees/worktree/refs/heads && + echo "ref: refs/heads/.invalid" >expect && + test_cmp expect repo/.git/worktrees/worktree/HEAD && + test_path_is_dir repo/.git/worktrees/worktree/reftable && + test_path_is_file repo/.git/worktrees/worktree/reftable/tables.list +' + +test_expect_success 'worktree: pack-refs in main repo packs main refs' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo A && + git -C repo worktree add ../worktree && + + test_line_count = 3 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 4 repo/.git/reftable/tables.list && + git -C repo pack-refs && + test_line_count = 3 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list +' + +test_expect_success 'worktree: pack-refs in worktree packs worktree refs' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo A && + git -C repo worktree add ../worktree && + + test_line_count = 3 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 4 repo/.git/reftable/tables.list && + git -C worktree pack-refs && + test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 4 repo/.git/reftable/tables.list +' + +test_expect_success 'worktree: creating shared ref updates main stack' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo A && + + git -C repo worktree add ../worktree && + git -C repo pack-refs && + git -C worktree pack-refs && + test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list && + + git -C worktree update-ref refs/heads/shared HEAD && + test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 2 repo/.git/reftable/tables.list +' + +test_expect_success 'worktree: creating per-worktree ref updates worktree stack' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo A && + + git -C repo worktree add ../worktree && + git -C repo pack-refs && + git -C worktree pack-refs && + test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list && + + git -C worktree update-ref refs/bisect/per-worktree HEAD && + test_line_count = 2 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list +' + +test_expect_success 'worktree: creating per-worktree ref from main repo' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo A && + + git -C repo worktree add ../worktree && + git -C repo pack-refs && + git -C worktree pack-refs && + test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list && + + git -C repo update-ref worktrees/worktree/refs/bisect/per-worktree HEAD && + test_line_count = 2 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list +' + +test_expect_success 'worktree: creating per-worktree ref from second worktree' ' + test_when_finished "rm -rf repo wt1 wt2" && + git init repo && + test_commit -C repo A && + + git -C repo worktree add ../wt1 && + git -C repo worktree add ../wt2 && + git -C repo pack-refs && + git -C wt1 pack-refs && + git -C wt2 pack-refs && + test_line_count = 1 repo/.git/worktrees/wt1/reftable/tables.list && + test_line_count = 1 repo/.git/worktrees/wt2/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list && + + git -C wt1 update-ref worktrees/wt2/refs/bisect/per-worktree HEAD && + test_line_count = 1 repo/.git/worktrees/wt1/reftable/tables.list && + test_line_count = 2 repo/.git/worktrees/wt2/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list +' + +test_expect_success 'worktree: can create shared and per-worktree ref in one transaction' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo A && + + git -C repo worktree add ../worktree && + git -C repo pack-refs && + git -C worktree pack-refs && + test_line_count = 1 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 1 repo/.git/reftable/tables.list && + + cat >stdin <<-EOF && + create worktrees/worktree/refs/bisect/per-worktree HEAD + create refs/branches/shared HEAD + EOF + git -C repo update-ref --stdin <stdin && + test_line_count = 2 repo/.git/worktrees/worktree/reftable/tables.list && + test_line_count = 2 repo/.git/reftable/tables.list +' + +test_expect_success 'worktree: can access common refs' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo file1 && + git -C repo branch branch1 && + git -C repo worktree add ../worktree && + + echo refs/heads/worktree >expect && + git -C worktree symbolic-ref HEAD >actual && + test_cmp expect actual && + git -C worktree checkout branch1 +' + +test_expect_success 'worktree: adds worktree with detached HEAD' ' + test_when_finished "rm -rf repo worktree" && + + git init repo && + test_commit -C repo A && + git -C repo rev-parse main >expect && + + git -C repo worktree add --detach ../worktree main && + git -C worktree rev-parse HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'fetch: accessing FETCH_HEAD special ref works' ' + test_when_finished "rm -rf repo sub" && + + git init sub && + test_commit -C sub two && + git -C sub rev-parse HEAD >expect && + + git init repo && + test_commit -C repo one && + git -C repo fetch ../sub && + git -C repo rev-parse FETCH_HEAD >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t0611-reftable-httpd.sh b/t/t0611-reftable-httpd.sh new file mode 100755 index 0000000000..5e05b9c1f2 --- /dev/null +++ b/t/t0611-reftable-httpd.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +test_description='reftable HTTPD tests' + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-httpd.sh + +start_httpd + +REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo" + +test_expect_success 'serving ls-remote' ' + git init --ref-format=reftable -b main "$REPO" && + cd "$REPO" && + test_commit m1 && + >.git/git-daemon-export-ok && + git ls-remote "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" | cut -f 2-2 -d " " >actual && + cat >expect <<-EOF && + HEAD + refs/heads/main + refs/tags/m1 + EOF + test_cmp actual expect +' + +test_done diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index d73a0be1b9..e0c6482797 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -6,7 +6,7 @@ test_description='git cat-file' test_cmdmode_usage () { test_expect_code 129 "$@" 2>err && - grep "^error:.*is incompatible with" err + grep "^error: .* cannot be used together" err } for switches in \ @@ -1100,6 +1100,42 @@ test_expect_success 'cat-file --batch="batman" with --batch-all-objects will wor cmp expect actual ' +test_expect_success 'cat-file %(objectsize:disk) with --batch-all-objects' ' + # our state has both loose and packed objects, + # so find both for our expected output + { + find .git/objects/?? -type f | + awk -F/ "{ print \$0, \$3\$4 }" | + while read path oid + do + size=$(test_file_size "$path") && + echo "$oid $size" || + return 1 + done && + rawsz=$(test_oid rawsz) && + find .git/objects/pack -name "*.idx" | + while read idx + do + git show-index <"$idx" >idx.raw && + sort -nr <idx.raw >idx.sorted && + packsz=$(test_file_size "${idx%.idx}.pack") && + end=$((packsz - rawsz)) && + while read start oid rest + do + size=$((end - start)) && + end=$start && + echo "$oid $size" || + return 1 + done <idx.sorted || + return 1 + done + } >expect.raw && + sort <expect.raw >expect && + git cat-file --batch-all-objects \ + --batch-check="%(objectname) %(objectsize:disk)" >actual && + test_cmp expect actual +' + test_expect_success 'set up replacement object' ' orig=$(git rev-parse HEAD) && git cat-file commit $orig >orig && diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index f67611da28..e49b8024ac 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -334,7 +334,7 @@ test_expect_success 'cone mode: set with nested folders' ' test_expect_success 'cone mode: add independent path' ' git -C repo sparse-checkout set deep/deeper1 && - git -C repo sparse-checkout add folder1 && + git -C repo sparse-checkout add --end-of-options folder1 && cat >expect <<-\EOF && /* !/*/ @@ -886,6 +886,12 @@ test_expect_success 'by default, cone mode will error out when passed files' ' grep ".gitignore.*is not a directory" error ' +test_expect_success 'error on mistyped command line options' ' + test_must_fail git -C repo sparse-checkout add --sikp-checks .gitignore 2>error && + + grep "unknown option.*sikp-checks" error +' + test_expect_success 'by default, non-cone mode will warn on individual files' ' git -C repo sparse-checkout reapply --no-cone && git -C repo sparse-checkout add .gitignore 2>warning && diff --git a/t/t1300-config.sh b/t/t1300-config.sh index f4e2752134..31c3878687 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -1098,15 +1098,20 @@ test_expect_success SYMLINKS 'symlink to nonexistent configuration' ' test_must_fail git config --file=linktolinktonada --list ' -test_expect_success 'check split_cmdline return' " - git config alias.split-cmdline-fix 'echo \"' && - test_must_fail git split-cmdline-fix && - echo foo > foo && - git add foo && - git commit -m 'initial commit' && - git config branch.main.mergeoptions 'echo \"' && - test_must_fail git merge main -" +test_expect_success 'check split_cmdline return' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config alias.split-cmdline-fix "echo \"" && + test_must_fail git split-cmdline-fix && + echo foo >foo && + git add foo && + git commit -m "initial commit" && + git config branch.main.mergeoptions "echo \"" && + test_must_fail git merge main + ) +' test_expect_success 'git -c "key=value" support' ' cat >expect <<-\EOF && @@ -1157,10 +1162,16 @@ test_expect_success 'git -c works with aliases of builtins' ' ' test_expect_success 'aliases can be CamelCased' ' - test_config alias.CamelCased "rev-parse HEAD" && - git CamelCased >out && - git rev-parse HEAD >expect && - test_cmp expect out + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit A && + git config alias.CamelCased "rev-parse HEAD" && + git CamelCased >out && + git rev-parse HEAD >expect && + test_cmp expect out + ) ' test_expect_success 'git -c does not split values on equals' ' @@ -2009,11 +2020,11 @@ test_expect_success '--show-origin getting a single key' ' ' test_expect_success 'set up custom config file' ' - CUSTOM_CONFIG_FILE="custom.conf" && - cat >"$CUSTOM_CONFIG_FILE" <<-\EOF + cat >"custom.conf" <<-\EOF && [user] custom = true EOF + CUSTOM_CONFIG_FILE="$(test-tool path-utils real_path custom.conf)" ' test_expect_success !MINGW 'set up custom config file with special name characters' ' @@ -2052,22 +2063,33 @@ test_expect_success '--show-origin stdin with file include' ' ' test_expect_success '--show-origin blob' ' - blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") && - cat >expect <<-EOF && - blob:$blob user.custom=true - EOF - git config --blob=$blob --show-origin --list >output && - test_cmp expect output + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") && + cat >expect <<-EOF && + blob:$blob user.custom=true + EOF + git config --blob=$blob --show-origin --list >output && + test_cmp expect output + ) ' test_expect_success '--show-origin blob ref' ' - cat >expect <<-\EOF && - blob:main:custom.conf user.custom=true - EOF - git add "$CUSTOM_CONFIG_FILE" && - git commit -m "new config file" && - git config --blob=main:"$CUSTOM_CONFIG_FILE" --show-origin --list >output && - test_cmp expect output + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + cat >expect <<-\EOF && + blob:main:custom.conf user.custom=true + EOF + cp "$CUSTOM_CONFIG_FILE" custom.conf && + git add custom.conf && + git commit -m "new config file" && + git config --blob=main:custom.conf --show-origin --list >output && + test_cmp expect output + ) ' test_expect_success '--show-origin with --default' ' diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh index e5a0d65caa..b1eb5c01b8 100755 --- a/t/t1301-shared-repo.sh +++ b/t/t1301-shared-repo.sh @@ -137,22 +137,6 @@ test_expect_success POSIXPERM 'info/refs respects umask in unshared repo' ' test_cmp expect actual ' -test_expect_success POSIXPERM 'git reflog expire honors core.sharedRepository' ' - umask 077 && - git config core.sharedRepository group && - git reflog expire --all && - actual="$(ls -l .git/logs/refs/heads/main)" && - case "$actual" in - -rw-rw-*) - : happy - ;; - *) - echo Ooops, .git/logs/refs/heads/main is not 066x [$actual] - false - ;; - esac -' - test_expect_success POSIXPERM 'forced modes' ' test_when_finished "rm -rf new" && mkdir -p templates/hooks && diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh index 179474fa65..42caa0d297 100755 --- a/t/t1302-repo-version.sh +++ b/t/t1302-repo-version.sh @@ -9,10 +9,6 @@ TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' - test_oid_cache <<-\EOF && - version sha1:0 - version sha256:1 - EOF cat >test.patch <<-\EOF && diff --git a/test.txt b/test.txt new file mode 100644 @@ -28,7 +24,12 @@ test_expect_success 'setup' ' ' test_expect_success 'gitdir selection on normal repos' ' - test_oid version >expect && + if test_have_prereq DEFAULT_REPO_FORMAT + then + echo 0 + else + echo 1 + fi >expect && git config core.repositoryformatversion >actual && git -C test config core.repositoryformatversion >actual2 && test_cmp expect actual && @@ -79,8 +80,13 @@ mkconfig () { while read outcome version extensions; do test_expect_success "$outcome version=$version $extensions" " - mkconfig $version $extensions >.git/config && - check_${outcome} + test_when_finished 'rm -rf extensions' && + git init extensions && + ( + cd extensions && + mkconfig $version $extensions >.git/config && + check_${outcome} + ) " done <<\EOF allow 0 @@ -94,7 +100,8 @@ allow 1 noop-v1 EOF test_expect_success 'precious-objects allowed' ' - mkconfig 1 preciousObjects >.git/config && + git config core.repositoryFormatVersion 1 && + git config extensions.preciousObjects 1 && check_allow ' diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index 9ac4b7036b..6ebc3ef945 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -9,8 +9,6 @@ test_description='Test git update-ref and basic ref logging' Z=$ZERO_OID m=refs/heads/main -n_dir=refs/heads/gu -n=$n_dir/fixes outside=refs/foo bare=bare-repo @@ -62,10 +60,10 @@ test_expect_success "delete $m without oldvalue verification" ' test_must_fail git show-ref --verify -q $m ' -test_expect_success "fail to create $n" ' - test_when_finished "rm -f .git/$n_dir" && - touch .git/$n_dir && - test_must_fail git update-ref $n $A +test_expect_success "fail to create $n due to file/directory conflict" ' + test_when_finished "git update-ref -d refs/heads/gu" && + git update-ref refs/heads/gu $A && + test_must_fail git update-ref refs/heads/gu/fixes $A ' test_expect_success "create $m (by HEAD)" ' @@ -92,7 +90,8 @@ test_expect_success "deleting current branch adds message to HEAD's log" ' git symbolic-ref HEAD $m && git update-ref -m delete-$m -d $m && test_must_fail git show-ref --verify -q $m && - grep "delete-$m$" .git/logs/HEAD + test-tool ref-store main for-each-reflog-ent HEAD >actual && + grep "delete-$m$" actual ' test_expect_success "deleting by HEAD adds message to HEAD's log" ' @@ -101,7 +100,8 @@ test_expect_success "deleting by HEAD adds message to HEAD's log" ' git symbolic-ref HEAD $m && git update-ref -m delete-by-head -d HEAD && test_must_fail git show-ref --verify -q $m && - grep "delete-by-head$" .git/logs/HEAD + test-tool ref-store main for-each-reflog-ent HEAD >actual && + grep "delete-by-head$" actual ' test_expect_success 'update-ref does not create reflogs by default' ' @@ -132,7 +132,7 @@ test_expect_success 'creates no reflog in bare repository' ' test_expect_success 'core.logAllRefUpdates=true creates reflog in bare repository' ' test_when_finished "git -C $bare config --unset core.logAllRefUpdates && \ - rm $bare/logs/$m" && + test-tool ref-store main delete-reflog $m" && git -C $bare config core.logAllRefUpdates true && git -C $bare update-ref $m $bareB && git -C $bare rev-parse $bareB >expect && @@ -221,27 +221,27 @@ test_expect_success 'delete symref without dereference when the referred ref is ' test_expect_success 'update-ref -d is not confused by self-reference' ' + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF refs/heads/self" && git symbolic-ref refs/heads/self refs/heads/self && - test_when_finished "rm -f .git/refs/heads/self" && - test_path_is_file .git/refs/heads/self && + git symbolic-ref --no-recurse refs/heads/self && test_must_fail git update-ref -d refs/heads/self && - test_path_is_file .git/refs/heads/self + git symbolic-ref --no-recurse refs/heads/self ' test_expect_success 'update-ref --no-deref -d can delete self-reference' ' + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF refs/heads/self" && git symbolic-ref refs/heads/self refs/heads/self && - test_when_finished "rm -f .git/refs/heads/self" && - test_path_is_file .git/refs/heads/self && + git symbolic-ref --no-recurse refs/heads/self && git update-ref --no-deref -d refs/heads/self && test_must_fail git show-ref --verify -q refs/heads/self ' -test_expect_success 'update-ref --no-deref -d can delete reference to bad ref' ' +test_expect_success REFFILES 'update-ref --no-deref -d can delete reference to bad ref' ' >.git/refs/heads/bad && test_when_finished "rm -f .git/refs/heads/bad" && git symbolic-ref refs/heads/ref-to-bad refs/heads/bad && test_when_finished "git update-ref -d refs/heads/ref-to-bad" && - test_path_is_file .git/refs/heads/ref-to-bad && + git symbolic-ref --no-recurse refs/heads/ref-to-bad && git update-ref --no-deref -d refs/heads/ref-to-bad && test_must_fail git show-ref --verify -q refs/heads/ref-to-bad ' @@ -265,7 +265,10 @@ test_expect_success "(not) changed .git/$m" ' ! test $B = $(git show-ref -s --verify $m) ' -rm -f .git/logs/refs/heads/main +test_expect_success "clean up reflog" ' + test-tool ref-store main delete-reflog $m +' + test_expect_success "create $m (logged by touch)" ' test_config core.logAllRefUpdates false && GIT_COMMITTER_DATE="2005-05-26 23:30" \ @@ -285,40 +288,13 @@ test_expect_success "set $m (logged by touch)" ' test $A = $(git show-ref -s --verify $m) ' -test_expect_success 'empty directory removal' ' - git branch d1/d2/r1 HEAD && - git branch d1/r2 HEAD && - test_path_is_file .git/refs/heads/d1/d2/r1 && - test_path_is_file .git/logs/refs/heads/d1/d2/r1 && - git branch -d d1/d2/r1 && - test_must_fail git show-ref --verify -q refs/heads/d1/d2 && - test_must_fail git show-ref --verify -q logs/refs/heads/d1/d2 && - test_path_is_file .git/refs/heads/d1/r2 && - test_path_is_file .git/logs/refs/heads/d1/r2 -' - -test_expect_success 'symref empty directory removal' ' - git branch e1/e2/r1 HEAD && - git branch e1/r2 HEAD && - git checkout e1/e2/r1 && - test_when_finished "git checkout main" && - test_path_is_file .git/refs/heads/e1/e2/r1 && - test_path_is_file .git/logs/refs/heads/e1/e2/r1 && - git update-ref -d HEAD && - test_must_fail git show-ref --verify -q refs/heads/e1/e2 && - test_must_fail git show-ref --verify -q logs/refs/heads/e1/e2 && - test_path_is_file .git/refs/heads/e1/r2 && - test_path_is_file .git/logs/refs/heads/e1/r2 && - test_path_is_file .git/logs/HEAD -' - cat >expect <<EOF $Z $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 Initial Creation $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150260 +0000 Switch $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000 EOF test_expect_success "verifying $m's log (logged by touch)" ' - test_when_finished "git update-ref -d $m && rm -rf .git/logs actual expect" && + test_when_finished "git update-ref -d $m && git reflog expire --expire=all --all && rm -rf actual expect" && test-tool ref-store main for-each-reflog-ent $m >actual && test_cmp actual expect ' @@ -348,20 +324,34 @@ $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 +0000 Switch $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 +0000 EOF test_expect_success "verifying $m's log (logged by config)" ' - test_when_finished "git update-ref -d $m && rm -rf .git/logs actual expect" && + test_when_finished "git update-ref -d $m && git reflog expire --expire=all --all && rm -rf actual expect" && test-tool ref-store main for-each-reflog-ent $m >actual && test_cmp actual expect ' test_expect_success 'set up for querying the reflog' ' + git update-ref -d $m && + test-tool ref-store main delete-reflog $m && + + GIT_COMMITTER_DATE="1117150320 -0500" git update-ref $m $C && + GIT_COMMITTER_DATE="1117150350 -0500" git update-ref $m $A && + GIT_COMMITTER_DATE="1117150380 -0500" git update-ref $m $B && + GIT_COMMITTER_DATE="1117150680 -0500" git update-ref $m $F && + GIT_COMMITTER_DATE="1117150980 -0500" git update-ref $m $E && git update-ref $m $D && - cat >.git/logs/$m <<-EOF + # Delete the last reflog entry so that the tip of m and the reflog for + # it disagree. + git reflog delete $m@{0} && + + cat >expect <<-EOF && $Z $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500 $C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500 $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500 - $F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500 - $Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500 + $B $F $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500 + $F $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500 EOF + test-tool ref-store main for-each-reflog-ent $m >actual && + test_cmp expect actual ' ed="Thu, 26 May 2005 18:32:00 -0500" @@ -409,13 +399,12 @@ test_expect_success 'Query "main@{2005-05-26 23:33:01}" (middle of history with test_when_finished "rm -f o e" && git rev-parse --verify "main@{2005-05-26 23:33:01}" >o 2>e && echo "$B" >expect && - test_cmp expect o && - test_grep -F "warning: log for ref $m has gap after $gd" e + test_cmp expect o ' test_expect_success 'Query "main@{2005-05-26 23:38:00}" (middle of history)' ' test_when_finished "rm -f o e" && git rev-parse --verify "main@{2005-05-26 23:38:00}" >o 2>e && - echo "$Z" >expect && + echo "$F" >expect && test_cmp expect o && test_must_be_empty e ' @@ -434,7 +423,24 @@ test_expect_success 'Query "main@{2005-05-28}" (past end of history)' ' test_grep -F "warning: log for ref $m unexpectedly ended on $ld" e ' -rm -f .git/$m .git/logs/$m expect +rm -f expect +git update-ref -d $m + +test_expect_success 'query reflog with gap' ' + test_when_finished "git update-ref -d $m" && + + GIT_COMMITTER_DATE="1117150320 -0500" git update-ref $m $A && + GIT_COMMITTER_DATE="1117150380 -0500" git update-ref $m $B && + GIT_COMMITTER_DATE="1117150480 -0500" git update-ref $m $C && + GIT_COMMITTER_DATE="1117150580 -0500" git update-ref $m $D && + GIT_COMMITTER_DATE="1117150680 -0500" git update-ref $m $F && + git reflog delete $m@{2} && + + git rev-parse --verify "main@{2005-05-26 23:33:01}" >actual 2>stderr && + echo "$B" >expect && + test_cmp expect actual && + test_grep -F "warning: log for ref $m has gap after $gd" stderr +' test_expect_success 'creating initial files' ' test_when_finished rm -f M && @@ -491,51 +497,51 @@ test_expect_success 'given old value for missing pseudoref, do not create' ' test_expect_success 'create pseudoref' ' git update-ref PSEUDOREF $A && - test $A = $(git rev-parse PSEUDOREF) + test $A = $(git show-ref -s --verify PSEUDOREF) ' test_expect_success 'overwrite pseudoref with no old value given' ' git update-ref PSEUDOREF $B && - test $B = $(git rev-parse PSEUDOREF) + test $B = $(git show-ref -s --verify PSEUDOREF) ' test_expect_success 'overwrite pseudoref with correct old value' ' git update-ref PSEUDOREF $C $B && - test $C = $(git rev-parse PSEUDOREF) + test $C = $(git show-ref -s --verify PSEUDOREF) ' test_expect_success 'do not overwrite pseudoref with wrong old value' ' test_must_fail git update-ref PSEUDOREF $D $E 2>err && - test $C = $(git rev-parse PSEUDOREF) && + test $C = $(git show-ref -s --verify PSEUDOREF) && test_grep "cannot lock ref.*expected" err ' test_expect_success 'delete pseudoref' ' git update-ref -d PSEUDOREF && - test_must_fail git rev-parse PSEUDOREF + test_must_fail git show-ref -s --verify PSEUDOREF ' test_expect_success 'do not delete pseudoref with wrong old value' ' git update-ref PSEUDOREF $A && test_must_fail git update-ref -d PSEUDOREF $B 2>err && - test $A = $(git rev-parse PSEUDOREF) && + test $A = $(git show-ref -s --verify PSEUDOREF) && test_grep "cannot lock ref.*expected" err ' test_expect_success 'delete pseudoref with correct old value' ' git update-ref -d PSEUDOREF $A && - test_must_fail git rev-parse PSEUDOREF + test_must_fail git show-ref -s --verify PSEUDOREF ' test_expect_success 'create pseudoref with old OID zero' ' git update-ref PSEUDOREF $A $Z && - test $A = $(git rev-parse PSEUDOREF) + test $A = $(git show-ref -s --verify PSEUDOREF) ' test_expect_success 'do not overwrite pseudoref with old OID zero' ' test_when_finished git update-ref -d PSEUDOREF && test_must_fail git update-ref PSEUDOREF $B $Z 2>err && - test $A = $(git rev-parse PSEUDOREF) && + test $A = $(git show-ref -s --verify PSEUDOREF) && test_grep "already exists" err ' @@ -1635,13 +1641,4 @@ test_expect_success PIPE 'transaction flushes status updates' ' test_cmp expected actual ' -test_expect_success 'directory not created deleting packed ref' ' - git branch d1/d2/r1 HEAD && - git pack-refs --all && - test_path_is_missing .git/refs/heads/d1/d2 && - git update-ref -d refs/heads/d1/d2/r1 && - test_path_is_missing .git/refs/heads/d1/d2 && - test_path_is_missing .git/refs/heads/d1 -' - test_done diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index c7745e1bf6..5c60d6f812 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -106,9 +106,8 @@ test_expect_success LONG_REF 'we can parse long symbolic ref' ' ' test_expect_success 'symbolic-ref reports failure in exit code' ' - test_when_finished "rm -f .git/HEAD.lock" && - >.git/HEAD.lock && - test_must_fail git symbolic-ref HEAD refs/heads/whatever + # Create d/f conflict to simulate failure. + test_must_fail git symbolic-ref refs/heads refs/heads/foo ' test_expect_success 'symbolic-ref writes reflog entry' ' @@ -171,8 +170,8 @@ test_expect_success 'symbolic-ref refuses invalid target for non-HEAD' ' ' test_expect_success 'symbolic-ref allows top-level target for non-HEAD' ' - git symbolic-ref refs/heads/top-level FETCH_HEAD && - git update-ref FETCH_HEAD HEAD && + git symbolic-ref refs/heads/top-level ORIG_HEAD && + git update-ref ORIG_HEAD HEAD && test_cmp_rev top-level HEAD ' diff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh index b50ae6fcf1..33fb7a38ff 100755 --- a/t/t1403-show-ref.sh +++ b/t/t1403-show-ref.sh @@ -174,6 +174,14 @@ test_expect_success 'show-ref --verify HEAD' ' test_must_be_empty actual ' +test_expect_success 'show-ref --verify pseudorefs' ' + git update-ref CHERRY_PICK_HEAD HEAD $ZERO_OID && + test_when_finished "git update-ref -d CHERRY_PICK_HEAD" && + git show-ref -s --verify HEAD >actual && + git show-ref -s --verify CHERRY_PICK_HEAD >expect && + test_cmp actual expect +' + test_expect_success 'show-ref --verify with dangling ref' ' sha1_file() { echo "$*" | sed "s#..#.git/objects/&/#" @@ -197,18 +205,20 @@ test_expect_success 'show-ref --verify with dangling ref' ' ' test_expect_success 'show-ref sub-modes are mutually exclusive' ' - cat >expect <<-EOF && - fatal: only one of ${SQ}--exclude-existing${SQ}, ${SQ}--verify${SQ} or ${SQ}--exists${SQ} can be given - EOF - test_must_fail git show-ref --verify --exclude-existing 2>err && - test_cmp expect err && + grep "verify" err && + grep "exclude-existing" err && + grep "cannot be used together" err && test_must_fail git show-ref --verify --exists 2>err && - test_cmp expect err && + grep "verify" err && + grep "exists" err && + grep "cannot be used together" err && test_must_fail git show-ref --exclude-existing --exists 2>err && - test_cmp expect err + grep "exclude-existing" err && + grep "exists" err && + grep "cannot be used together" err ' test_expect_success '--exists with existing reference' ' @@ -260,10 +270,20 @@ test_expect_success '--exists with non-commit object' ' test_expect_success '--exists with directory fails with generic error' ' cat >expect <<-EOF && - error: failed to look up reference: Is a directory + error: reference does not exist EOF - test_expect_code 1 git show-ref --exists refs/heads 2>err && + test_expect_code 2 git show-ref --exists refs/heads 2>err && test_cmp expect err ' +test_expect_success '--exists with non-existent special ref' ' + test_expect_code 2 git show-ref --exists FETCH_HEAD +' + +test_expect_success '--exists with existing special ref' ' + test_when_finished "rm .git/FETCH_HEAD" && + git rev-parse HEAD >.git/FETCH_HEAD && + git show-ref --exists FETCH_HEAD +' + test_done diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh index 0369beea33..98e9158bd2 100755 --- a/t/t1404-update-ref-errors.sh +++ b/t/t1404-update-ref-errors.sh @@ -92,9 +92,6 @@ df_test() { else delname="$delref" fi && - cat >expected-err <<-EOF && - fatal: cannot lock ref $SQ$addname$SQ: $SQ$delref$SQ exists; cannot create $SQ$addref$SQ - EOF $pack && if $add_del then @@ -103,7 +100,7 @@ df_test() { printf "%s\n" "delete $delname" "create $addname $D" fi >commands && test_must_fail git update-ref --stdin <commands 2>output.err && - test_cmp expected-err output.err && + grep "fatal:\( cannot lock ref $SQ$addname$SQ:\)\? $SQ$delref$SQ exists; cannot create $SQ$addref$SQ" output.err && printf "%s\n" "$C $delref" >expected-refs && git for-each-ref --format="%(objectname) %(refname)" $prefix/r >actual-refs && test_cmp expected-refs actual-refs @@ -191,141 +188,69 @@ test_expect_success 'one new ref is a simple prefix of another' ' ' -test_expect_success REFFILES 'empty directory should not fool rev-parse' ' - prefix=refs/e-rev-parse && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - echo "$C" >expected && - git rev-parse $prefix/foo >actual && - test_cmp expected actual -' - -test_expect_success REFFILES 'empty directory should not fool for-each-ref' ' - prefix=refs/e-for-each-ref && - git update-ref $prefix/foo $C && - git for-each-ref $prefix >expected && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - git for-each-ref $prefix >actual && - test_cmp expected actual -' - -test_expect_success REFFILES 'empty directory should not fool create' ' - prefix=refs/e-create && - mkdir -p .git/$prefix/foo/bar/baz && - printf "create %s $C\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool verify' ' - prefix=refs/e-verify && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "verify %s $C\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool 1-arg update' ' - prefix=refs/e-update-1 && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "update %s $D\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool 2-arg update' ' - prefix=refs/e-update-2 && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "update %s $D $C\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool 0-arg delete' ' - prefix=refs/e-delete-0 && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "delete %s\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'empty directory should not fool 1-arg delete' ' - prefix=refs/e-delete-1 && - git update-ref $prefix/foo $C && - git pack-refs --all && - mkdir -p .git/$prefix/foo/bar/baz && - printf "delete %s $C\n" $prefix/foo | - git update-ref --stdin -' - -test_expect_success REFFILES 'D/F conflict prevents add long + delete short' ' +test_expect_success 'D/F conflict prevents add long + delete short' ' df_test refs/df-al-ds --add-del foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents add short + delete long' ' +test_expect_success 'D/F conflict prevents add short + delete long' ' df_test refs/df-as-dl --add-del foo foo/bar ' -test_expect_success REFFILES 'D/F conflict prevents delete long + add short' ' +test_expect_success 'D/F conflict prevents delete long + add short' ' df_test refs/df-dl-as --del-add foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents delete short + add long' ' +test_expect_success 'D/F conflict prevents delete short + add long' ' df_test refs/df-ds-al --del-add foo foo/bar ' -test_expect_success REFFILES 'D/F conflict prevents add long + delete short packed' ' +test_expect_success 'D/F conflict prevents add long + delete short packed' ' df_test refs/df-al-dsp --pack --add-del foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents add short + delete long packed' ' +test_expect_success 'D/F conflict prevents add short + delete long packed' ' df_test refs/df-as-dlp --pack --add-del foo foo/bar ' -test_expect_success REFFILES 'D/F conflict prevents delete long packed + add short' ' +test_expect_success 'D/F conflict prevents delete long packed + add short' ' df_test refs/df-dlp-as --pack --del-add foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents delete short packed + add long' ' +test_expect_success 'D/F conflict prevents delete short packed + add long' ' df_test refs/df-dsp-al --pack --del-add foo foo/bar ' # Try some combinations involving symbolic refs... -test_expect_success REFFILES 'D/F conflict prevents indirect add long + delete short' ' +test_expect_success 'D/F conflict prevents indirect add long + delete short' ' df_test refs/df-ial-ds --sym-add --add-del foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents indirect add long + indirect delete short' ' +test_expect_success 'D/F conflict prevents indirect add long + indirect delete short' ' df_test refs/df-ial-ids --sym-add --sym-del --add-del foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents indirect add short + indirect delete long' ' +test_expect_success 'D/F conflict prevents indirect add short + indirect delete long' ' df_test refs/df-ias-idl --sym-add --sym-del --add-del foo foo/bar ' -test_expect_success REFFILES 'D/F conflict prevents indirect delete long + indirect add short' ' +test_expect_success 'D/F conflict prevents indirect delete long + indirect add short' ' df_test refs/df-idl-ias --sym-add --sym-del --del-add foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents indirect add long + delete short packed' ' +test_expect_success 'D/F conflict prevents indirect add long + delete short packed' ' df_test refs/df-ial-dsp --sym-add --pack --add-del foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents indirect add long + indirect delete short packed' ' +test_expect_success 'D/F conflict prevents indirect add long + indirect delete short packed' ' df_test refs/df-ial-idsp --sym-add --sym-del --pack --add-del foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents add long + indirect delete short packed' ' +test_expect_success 'D/F conflict prevents add long + indirect delete short packed' ' df_test refs/df-al-idsp --sym-del --pack --add-del foo/bar foo ' -test_expect_success REFFILES 'D/F conflict prevents indirect delete long packed + indirect add short' ' +test_expect_success 'D/F conflict prevents indirect delete long packed + indirect add short' ' df_test refs/df-idlp-ias --sym-add --sym-del --pack --del-add foo/bar foo ' @@ -468,169 +393,4 @@ test_expect_success 'incorrect old value blocks indirect no-deref delete' ' test_cmp expected output.err ' -test_expect_success REFFILES 'non-empty directory blocks create' ' - prefix=refs/ne-create && - mkdir -p .git/$prefix/foo/bar && - : >.git/$prefix/foo/bar/baz.lock && - test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/foo$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ - EOF - printf "%s\n" "update $prefix/foo $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ - EOF - printf "%s\n" "update $prefix/foo $D $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err -' - -test_expect_success REFFILES 'broken reference blocks create' ' - prefix=refs/broken-create && - mkdir -p .git/$prefix && - echo "gobbledigook" >.git/$prefix/foo && - test_when_finished "rm -f .git/$prefix/foo" && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken - EOF - printf "%s\n" "update $prefix/foo $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/foo$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken - EOF - printf "%s\n" "update $prefix/foo $D $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err -' - -test_expect_success REFFILES 'non-empty directory blocks indirect create' ' - prefix=refs/ne-indirect-create && - git symbolic-ref $prefix/symref $prefix/foo && - mkdir -p .git/$prefix/foo/bar && - : >.git/$prefix/foo/bar/baz.lock && - test_when_finished "rm -f .git/$prefix/foo/bar/baz.lock" && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/symref$SQ: there is a non-empty directory $SQ.git/$prefix/foo$SQ blocking reference $SQ$prefix/foo$SQ - EOF - printf "%s\n" "update $prefix/symref $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ - EOF - printf "%s\n" "update $prefix/symref $D $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err -' - -test_expect_success REFFILES 'broken reference blocks indirect create' ' - prefix=refs/broken-indirect-create && - git symbolic-ref $prefix/symref $prefix/foo && - echo "gobbledigook" >.git/$prefix/foo && - test_when_finished "rm -f .git/$prefix/foo" && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken - EOF - printf "%s\n" "update $prefix/symref $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err && - cat >expected <<-EOF && - fatal: cannot lock ref $SQ$prefix/symref$SQ: unable to resolve reference $SQ$prefix/foo$SQ: reference broken - EOF - printf "%s\n" "update $prefix/symref $D $C" | - test_must_fail git update-ref --stdin 2>output.err && - test_cmp expected output.err -' - -test_expect_success REFFILES 'no bogus intermediate values during delete' ' - prefix=refs/slow-transaction && - # Set up a reference with differing loose and packed versions: - git update-ref $prefix/foo $C && - git pack-refs --all && - git update-ref $prefix/foo $D && - # Now try to update the reference, but hold the `packed-refs` lock - # for a while to see what happens while the process is blocked: - : >.git/packed-refs.lock && - test_when_finished "rm -f .git/packed-refs.lock" && - { - # Note: the following command is intentionally run in the - # background. We increase the timeout so that `update-ref` - # attempts to acquire the `packed-refs` lock for much longer - # than it takes for us to do the check then delete it: - git -c core.packedrefstimeout=30000 update-ref -d $prefix/foo & - } && - pid2=$! && - # Give update-ref plenty of time to get to the point where it tries - # to lock packed-refs: - sleep 1 && - # Make sure that update-ref did not complete despite the lock: - kill -0 $pid2 && - # Verify that the reference still has its old value: - sha1=$(git rev-parse --verify --quiet $prefix/foo || echo undefined) && - case "$sha1" in - $D) - # This is what we hope for; it means that nothing - # user-visible has changed yet. - : ;; - undefined) - # This is not correct; it means the deletion has happened - # already even though update-ref should not have been - # able to acquire the lock yet. - echo "$prefix/foo deleted prematurely" && - break - ;; - $C) - # This value should never be seen. Probably the loose - # reference has been deleted but the packed reference - # is still there: - echo "$prefix/foo incorrectly observed to be C" && - break - ;; - *) - # WTF? - echo "unexpected value observed for $prefix/foo: $sha1" && - break - ;; - esac >out && - rm -f .git/packed-refs.lock && - wait $pid2 && - test_must_be_empty out && - test_must_fail git rev-parse --verify --quiet $prefix/foo -' - -test_expect_success REFFILES 'delete fails cleanly if packed-refs file is locked' ' - prefix=refs/locked-packed-refs && - # Set up a reference with differing loose and packed versions: - git update-ref $prefix/foo $C && - git pack-refs --all && - git update-ref $prefix/foo $D && - git for-each-ref $prefix >unchanged && - # Now try to delete it while the `packed-refs` lock is held: - : >.git/packed-refs.lock && - test_when_finished "rm -f .git/packed-refs.lock" && - test_must_fail git update-ref -d $prefix/foo >out 2>err && - git for-each-ref $prefix >actual && - test_grep "Unable to create $SQ.*packed-refs.lock$SQ: " err && - test_cmp unchanged actual -' - -test_expect_success REFFILES 'delete fails cleanly if packed-refs.new write fails' ' - # Setup and expectations are similar to the test above. - prefix=refs/failed-packed-refs && - git update-ref $prefix/foo $C && - git pack-refs --all && - git update-ref $prefix/foo $D && - git for-each-ref $prefix >unchanged && - # This should not happen in practice, but it is an easy way to get a - # reliable error (we open with create_tempfile(), which uses O_EXCL). - : >.git/packed-refs.new && - test_when_finished "rm -f .git/packed-refs.new" && - test_must_fail git update-ref -d $prefix/foo && - git for-each-ref $prefix >actual && - test_cmp unchanged actual -' - test_done diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index e4627cf1b6..a6bcd62ab6 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -15,14 +15,6 @@ test_expect_success 'setup' ' test_commit one ' -test_expect_success REFFILES 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' ' - N=`find .git/refs -type f | wc -l` && - test "$N" != 0 && - $RUN pack-refs PACK_REFS_PRUNE,PACK_REFS_ALL && - N=`find .git/refs -type f` && - test -z "$N" -' - test_expect_success 'create_symref(FOO, refs/heads/main)' ' $RUN create-symref FOO refs/heads/main nothing && echo refs/heads/main >expected && @@ -41,12 +33,6 @@ test_expect_success 'delete_refs(FOO, refs/tags/new-tag)' ' test_must_fail git rev-parse refs/tags/new-tag -- ' -# In reftable, we keep the reflogs around for deleted refs. -test_expect_success !REFFILES 'delete-reflog(FOO, refs/tags/new-tag)' ' - $RUN delete-reflog FOO && - $RUN delete-reflog refs/tags/new-tag -' - test_expect_success 'rename_refs(main, new-main)' ' git rev-parse main >expected && $RUN rename-ref refs/heads/main refs/heads/new-main && @@ -82,11 +68,11 @@ test_expect_success 'verify_ref(new-main)' ' ' test_expect_success 'for_each_reflog()' ' - $RUN for-each-reflog | sort -k2 | cut -d" " -f 2- >actual && + $RUN for-each-reflog >actual && cat >expected <<-\EOF && - HEAD 0x1 - refs/heads/main 0x0 - refs/heads/new-main 0x0 + HEAD + refs/heads/main + refs/heads/new-main EOF test_cmp expected actual ' @@ -112,7 +98,7 @@ test_expect_success 'delete_reflog(HEAD)' ' test_must_fail git reflog exists HEAD ' -test_expect_success REFFILES 'create-reflog(HEAD)' ' +test_expect_success 'create-reflog(HEAD)' ' $RUN create-reflog HEAD && git reflog exists HEAD ' diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh index e6a7f7334b..c01f0f14a1 100755 --- a/t/t1406-submodule-ref-store.sh +++ b/t/t1406-submodule-ref-store.sh @@ -63,11 +63,11 @@ test_expect_success 'verify_ref(new-main)' ' ' test_expect_success 'for_each_reflog()' ' - $RUN for-each-reflog | sort | cut -d" " -f 2- >actual && + $RUN for-each-reflog >actual && cat >expected <<-\EOF && - HEAD 0x1 - refs/heads/main 0x0 - refs/heads/new-main 0x0 + HEAD + refs/heads/main + refs/heads/new-main EOF test_cmp expected actual ' diff --git a/t/t1407-worktree-ref-store.sh b/t/t1407-worktree-ref-store.sh index 05b1881c59..48b1c92a41 100755 --- a/t/t1407-worktree-ref-store.sh +++ b/t/t1407-worktree-ref-store.sh @@ -53,41 +53,4 @@ test_expect_success 'create_symref(FOO, refs/heads/main)' ' test_cmp expected actual ' -# Some refs (refs/bisect/*, pseudorefs) are kept per worktree, so they should -# only appear in the for-each-reflog output if it is called from the correct -# worktree, which is exercised in this test. This test is poorly written (and -# therefore marked REFFILES) for mulitple reasons: 1) it creates invalidly -# formatted log entres. 2) it uses direct FS access for creating the reflogs. 3) -# PSEUDO-WT and refs/bisect/random do not create reflogs by default, so it is -# not testing a realistic scenario. -test_expect_success REFFILES 'for_each_reflog()' ' - echo $ZERO_OID > .git/logs/PSEUDO-MAIN && - mkdir -p .git/logs/refs/bisect && - echo $ZERO_OID > .git/logs/refs/bisect/random && - - echo $ZERO_OID > .git/worktrees/wt/logs/PSEUDO-WT && - mkdir -p .git/worktrees/wt/logs/refs/bisect && - echo $ZERO_OID > .git/worktrees/wt/logs/refs/bisect/wt-random && - - $RWT for-each-reflog | cut -d" " -f 2- | sort >actual && - cat >expected <<-\EOF && - HEAD 0x1 - PSEUDO-WT 0x0 - refs/bisect/wt-random 0x0 - refs/heads/main 0x0 - refs/heads/wt-main 0x0 - EOF - test_cmp expected actual && - - $RMAIN for-each-reflog | cut -d" " -f 2- | sort >actual && - cat >expected <<-\EOF && - HEAD 0x1 - PSEUDO-MAIN 0x0 - refs/bisect/random 0x0 - refs/heads/main 0x0 - refs/heads/wt-main 0x0 - EOF - test_cmp expected actual -' - test_done diff --git a/t/t1409-avoid-packing-refs.sh b/t/t1409-avoid-packing-refs.sh index f23c0152a8..7748973733 100755 --- a/t/t1409-avoid-packing-refs.sh +++ b/t/t1409-avoid-packing-refs.sh @@ -5,6 +5,12 @@ test_description='avoid rewriting packed-refs unnecessarily' TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping files-backend specific pack-refs tests' + test_done +fi + # Add an identifying mark to the packed-refs file header line. This # shouldn't upset readers, and it should be omitted if the file is # ever rewritten. diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index aeddc2fb3f..5bf883f1e3 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -354,36 +354,6 @@ test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' ' test_must_be_empty actual ' -# Triggering the bug detected by this test requires a newline to fall -# exactly BUFSIZ-1 bytes from the end of the file. We don't know -# what that value is, since it's platform dependent. However, if -# we choose some value N, we also catch any D which divides N evenly -# (since we will read backwards in chunks of D). So we choose 8K, -# which catches glibc (with an 8K BUFSIZ) and *BSD (1K). -# -# Each line is 114 characters, so we need 75 to still have a few before the -# last 8K. The 89-character padding on the final entry lines up our -# newline exactly. -test_expect_success REFFILES,SHA1 'parsing reverse reflogs at BUFSIZ boundaries' ' - git checkout -b reflogskip && - zf=$(test_oid zero_2) && - ident="abc <xyz> 0000000001 +0000" && - for i in $(test_seq 1 75); do - printf "$zf%02d $zf%02d %s\t" $i $(($i+1)) "$ident" && - if test $i = 75; then - for j in $(test_seq 1 89); do - printf X || return 1 - done - else - printf X - fi && - printf "\n" || return 1 - done >.git/logs/refs/heads/reflogskip && - git rev-parse reflogskip@{73} >actual && - echo ${zf}03 >expect && - test_cmp expect actual -' - test_expect_success 'no segfaults for reflog containing non-commit sha1s' ' git update-ref --create-reflog -m "Creating ref" \ refs/tests/tree-in-reflog HEAD && @@ -397,18 +367,6 @@ test_expect_failure 'reflog with non-commit entries displays all entries' ' test_line_count = 3 actual ' -# This test takes a lock on an individual ref; this is not supported in -# reftable. -test_expect_success REFFILES 'reflog expire operates on symref not referrent' ' - git branch --create-reflog the_symref && - git branch --create-reflog referrent && - git update-ref referrent HEAD && - git symbolic-ref refs/heads/the_symref refs/heads/referrent && - test_when_finished "rm -f .git/refs/heads/referrent.lock" && - touch .git/refs/heads/referrent.lock && - git reflog expire --expire=all the_symref -' - test_expect_success 'continue walking past root commits' ' git init orphanage && ( @@ -469,13 +427,121 @@ test_expect_success 'expire one of multiple worktrees' ' ) ' -test_expect_success REFFILES 'empty reflog' ' +test_expect_success 'empty reflog' ' test_when_finished "rm -rf empty" && git init empty && test_commit -C empty A && - >empty/.git/logs/refs/heads/foo && + test-tool ref-store main create-reflog refs/heads/foo && git -C empty reflog expire --all 2>err && test_must_be_empty err ' +test_expect_success 'list reflogs' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git reflog list >actual && + test_must_be_empty actual && + + test_commit A && + cat >expect <<-EOF && + HEAD + refs/heads/main + EOF + git reflog list >actual && + test_cmp expect actual && + + git branch b && + cat >expect <<-EOF && + HEAD + refs/heads/b + refs/heads/main + EOF + git reflog list >actual && + test_cmp expect actual + ) +' + +test_expect_success 'list reflogs with worktree' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + + test_commit A && + git worktree add wt && + git -c core.logAllRefUpdates=always \ + update-ref refs/worktree/main HEAD && + git -c core.logAllRefUpdates=always \ + update-ref refs/worktree/per-worktree HEAD && + git -c core.logAllRefUpdates=always -C wt \ + update-ref refs/worktree/per-worktree HEAD && + git -c core.logAllRefUpdates=always -C wt \ + update-ref refs/worktree/worktree HEAD && + + cat >expect <<-EOF && + HEAD + refs/heads/main + refs/heads/wt + refs/worktree/main + refs/worktree/per-worktree + EOF + git reflog list >actual && + test_cmp expect actual && + + cat >expect <<-EOF && + HEAD + refs/heads/main + refs/heads/wt + refs/worktree/per-worktree + refs/worktree/worktree + EOF + git -C wt reflog list >actual && + test_cmp expect actual + ) +' + +test_expect_success 'reflog list returns error with additional args' ' + cat >expect <<-EOF && + error: list does not accept arguments: ${SQ}bogus${SQ} + EOF + test_must_fail git reflog list bogus 2>err && + test_cmp expect err +' + +test_expect_success 'reflog for symref with unborn target can be listed' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit A && + git symbolic-ref HEAD refs/heads/unborn && + cat >expect <<-EOF && + HEAD + refs/heads/main + EOF + git reflog list >actual && + test_cmp expect actual + ) +' + +test_expect_success 'reflog with invalid object ID can be listed' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit A && + test-tool ref-store main update-ref msg refs/heads/missing \ + $(test_oid deadbeef) "$ZERO_OID" REF_SKIP_OID_VERIFICATION && + cat >expect <<-EOF && + HEAD + refs/heads/main + refs/heads/missing + EOF + git reflog list >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t1414-reflog-walk.sh b/t/t1414-reflog-walk.sh index ea64cecf47..be6c3f472c 100755 --- a/t/t1414-reflog-walk.sh +++ b/t/t1414-reflog-walk.sh @@ -121,13 +121,12 @@ test_expect_success 'min/max age uses entry date to limit' ' # Create a situation where the reflog and ref database disagree about the latest # state of HEAD. -test_expect_success REFFILES 'walk prefers reflog to ref tip' ' +test_expect_success 'walk prefers reflog to ref tip' ' + test_commit A && + test_commit B && + git reflog delete HEAD@{0} && head=$(git rev-parse HEAD) && - one=$(git rev-parse one) && - ident="$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" && - echo "$head $one $ident broken reflog entry" >>.git/logs/HEAD && - - echo $one >expect && + git rev-parse A >expect && git log -g --format=%H -1 >actual && test_cmp expect actual ' diff --git a/t/t1415-worktree-refs.sh b/t/t1415-worktree-refs.sh index 3b531842dd..eb4eec8bec 100755 --- a/t/t1415-worktree-refs.sh +++ b/t/t1415-worktree-refs.sh @@ -17,17 +17,6 @@ test_expect_success 'setup' ' git -C wt2 update-ref refs/worktree/foo HEAD ' -# The 'packed-refs' file is stored directly in .git/. This means it is global -# to the repository, and can only contain refs that are shared across all -# worktrees. -test_expect_success REFFILES 'refs/worktree must not be packed' ' - git pack-refs --all && - test_path_is_missing .git/refs/tags/wt1 && - test_path_is_file .git/refs/worktree/foo && - test_path_is_file .git/worktrees/wt1/refs/worktree/foo && - test_path_is_file .git/worktrees/wt2/refs/worktree/foo -' - test_expect_success 'refs/worktree are per-worktree' ' test_cmp_rev worktree/foo initial && ( cd wt1 && test_cmp_rev worktree/foo wt1 ) && diff --git a/t/t1417-reflog-updateref.sh b/t/t1417-reflog-updateref.sh index 14f13b57c6..0eb5e674bc 100755 --- a/t/t1417-reflog-updateref.sh +++ b/t/t1417-reflog-updateref.sh @@ -14,9 +14,13 @@ test_expect_success 'setup' ' test_commit B && test_commit C && - cp .git/logs/HEAD HEAD.old && + git reflog HEAD >expect && git reset --hard HEAD~ && - cp HEAD.old .git/logs/HEAD + # Make sure that the reflog does not point to the same commit + # as HEAD. + git reflog delete HEAD@{0} && + git reflog HEAD >actual && + test_cmp expect actual ) ' @@ -25,7 +29,7 @@ test_reflog_updateref () { shift args="$@" - test_expect_success REFFILES "get '$exp' with '$args'" ' + test_expect_success "get '$exp' with '$args'" ' test_when_finished "rm -rf copy" && cp -R repo copy && diff --git a/t/t1419-exclude-refs.sh b/t/t1419-exclude-refs.sh index 5d8c86b657..1359574419 100755 --- a/t/t1419-exclude-refs.sh +++ b/t/t1419-exclude-refs.sh @@ -8,6 +8,12 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +if test_have_prereq !REFFILES +then + skip_all='skipping `git for-each-ref --exclude` tests; need files backend' + test_done +fi + for_each_ref__exclude () { GIT_TRACE2_PERF=1 test-tool ref-store main \ for-each-ref--exclude "$@" >actual.raw diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh index 68cc9e73d0..0c00118c2b 100755 --- a/t/t1430-bad-ref-name.sh +++ b/t/t1430-bad-ref-name.sh @@ -164,9 +164,9 @@ test_expect_success 'rev-parse skips symref pointing to broken name' ' test_expect_success 'for-each-ref emits warnings for broken names' ' test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && - printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && + test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && - printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref && + test-tool ref-store main create-symref refs/heads/broken...symref refs/heads/main && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && git for-each-ref >output 2>error && ! grep -e "broken\.\.\.ref" output && @@ -257,7 +257,7 @@ test_expect_success 'update-ref -d can delete broken name through symref' ' ' test_expect_success 'update-ref --no-deref -d can delete symref with broken name' ' - printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref && + test-tool ref-store main create-symref refs/heads/broken...symref refs/heads/main && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && test_ref_exists refs/heads/broken...symref && git update-ref --no-deref -d refs/heads/broken...symref >output 2>error && @@ -267,7 +267,7 @@ test_expect_success 'update-ref --no-deref -d can delete symref with broken name ' test_expect_success 'branch -d can delete symref with broken name' ' - printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref && + test-tool ref-store main create-symref refs/heads/broken...symref refs/heads/main && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && test_ref_exists refs/heads/broken...symref && git branch -d broken...symref >output 2>error && @@ -277,7 +277,7 @@ test_expect_success 'branch -d can delete symref with broken name' ' ' test_expect_success 'update-ref --no-deref -d can delete dangling symref with broken name' ' - printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref && + test-tool ref-store main create-symref refs/heads/broken...symref refs/heads/idonotexist && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && test_ref_exists refs/heads/broken...symref && git update-ref --no-deref -d refs/heads/broken...symref >output 2>error && @@ -287,7 +287,7 @@ test_expect_success 'update-ref --no-deref -d can delete dangling symref with br ' test_expect_success 'branch -d can delete dangling symref with broken name' ' - printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref && + test-tool ref-store main create-symref refs/heads/broken...symref refs/heads/idonotexist && test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && test_ref_exists refs/heads/broken...symref && git branch -d broken...symref >output 2>error && diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 0e3e87d37a..8a456b1142 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -15,6 +15,7 @@ test_expect_success setup ' git config --unset i18n.commitencoding && git checkout HEAD^0 && test_commit B fileB two && + orig_head=$(git rev-parse HEAD) && git tag -d A B && git reflog expire --expire=now --all ' @@ -115,15 +116,15 @@ test_expect_success 'zlib corrupt loose object output ' ' ' test_expect_success 'branch pointing to non-commit' ' - git rev-parse HEAD^{tree} >.git/refs/heads/invalid && + tree_oid=$(git rev-parse --verify HEAD^{tree}) && test_when_finished "git update-ref -d refs/heads/invalid" && + test-tool ref-store main update-ref msg refs/heads/invalid $tree_oid $ZERO_OID REF_SKIP_OID_VERIFICATION && test_must_fail git fsck 2>out && test_grep "not a commit" out ' -test_expect_success 'HEAD link pointing at a funny object' ' - test_when_finished "mv .git/SAVED_HEAD .git/HEAD" && - mv .git/HEAD .git/SAVED_HEAD && +test_expect_success REFFILES 'HEAD link pointing at a funny object' ' + test_when_finished "git update-ref HEAD $orig_head" && echo $ZERO_OID >.git/HEAD && # avoid corrupt/broken HEAD from interfering with repo discovery test_must_fail env GIT_DIR=.git git fsck 2>out && @@ -131,27 +132,25 @@ test_expect_success 'HEAD link pointing at a funny object' ' ' test_expect_success 'HEAD link pointing at a funny place' ' - test_when_finished "mv .git/SAVED_HEAD .git/HEAD" && - mv .git/HEAD .git/SAVED_HEAD && - echo "ref: refs/funny/place" >.git/HEAD && + test_when_finished "git update-ref --no-deref HEAD $orig_head" && + test-tool ref-store main create-symref HEAD refs/funny/place && # avoid corrupt/broken HEAD from interfering with repo discovery test_must_fail env GIT_DIR=.git git fsck 2>out && test_grep "HEAD points to something strange" out ' -test_expect_success 'HEAD link pointing at a funny object (from different wt)' ' - test_when_finished "mv .git/SAVED_HEAD .git/HEAD" && - test_when_finished "rm -rf .git/worktrees wt" && +test_expect_success REFFILES 'HEAD link pointing at a funny object (from different wt)' ' + test_when_finished "git update-ref HEAD $orig_head" && + test_when_finished "git worktree remove -f wt" && git worktree add wt && - mv .git/HEAD .git/SAVED_HEAD && echo $ZERO_OID >.git/HEAD && # avoid corrupt/broken HEAD from interfering with repo discovery test_must_fail git -C wt fsck 2>out && test_grep "main-worktree/HEAD: detached HEAD points" out ' -test_expect_success 'other worktree HEAD link pointing at a funny object' ' - test_when_finished "rm -rf .git/worktrees other" && +test_expect_success REFFILES 'other worktree HEAD link pointing at a funny object' ' + test_when_finished "git worktree remove -f other" && git worktree add other && echo $ZERO_OID >.git/worktrees/other/HEAD && test_must_fail git fsck 2>out && @@ -159,17 +158,18 @@ test_expect_success 'other worktree HEAD link pointing at a funny object' ' ' test_expect_success 'other worktree HEAD link pointing at missing object' ' - test_when_finished "rm -rf .git/worktrees other" && + test_when_finished "git worktree remove -f other" && git worktree add other && - echo "Contents missing from repo" | git hash-object --stdin >.git/worktrees/other/HEAD && + object_id=$(echo "Contents missing from repo" | git hash-object --stdin) && + test-tool -C other ref-store main update-ref msg HEAD $object_id "" REF_NO_DEREF,REF_SKIP_OID_VERIFICATION && test_must_fail git fsck 2>out && test_grep "worktrees/other/HEAD: invalid sha1 pointer" out ' test_expect_success 'other worktree HEAD link pointing at a funny place' ' - test_when_finished "rm -rf .git/worktrees other" && + test_when_finished "git worktree remove -f other" && git worktree add other && - echo "ref: refs/funny/place" >.git/worktrees/other/HEAD && + git -C other symbolic-ref HEAD refs/funny/place && test_must_fail git fsck 2>out && test_grep "worktrees/other/HEAD points to something strange" out ' @@ -391,7 +391,7 @@ test_expect_success 'tag pointing to nonexistent' ' tag=$(git hash-object -t tag -w --stdin <invalid-tag) && test_when_finished "remove_object $tag" && - echo $tag >.git/refs/tags/invalid && + git update-ref refs/tags/invalid $tag && test_when_finished "git update-ref -d refs/tags/invalid" && test_must_fail git fsck --tags >out && test_grep "broken link" out @@ -411,7 +411,7 @@ test_expect_success 'tag pointing to something else than its type' ' tag=$(git hash-object -t tag -w --stdin <wrong-tag) && test_when_finished "remove_object $tag" && - echo $tag >.git/refs/tags/wrong && + git update-ref refs/tags/wrong $tag && test_when_finished "git update-ref -d refs/tags/wrong" && test_must_fail git fsck --tags ' @@ -428,7 +428,7 @@ test_expect_success 'tag with incorrect tag name & missing tagger' ' tag=$(git hash-object --literally -t tag -w --stdin <wrong-tag) && test_when_finished "remove_object $tag" && - echo $tag >.git/refs/tags/wrong && + git update-ref refs/tags/wrong $tag && test_when_finished "git update-ref -d refs/tags/wrong" && git fsck --tags 2>out && @@ -452,7 +452,7 @@ test_expect_success 'tag with bad tagger' ' tag=$(git hash-object --literally -t tag -w --stdin <wrong-tag) && test_when_finished "remove_object $tag" && - echo $tag >.git/refs/tags/wrong && + git update-ref refs/tags/wrong $tag && test_when_finished "git update-ref -d refs/tags/wrong" && test_must_fail git fsck --tags 2>out && test_grep "error in tag .*: invalid author/committer" out @@ -471,7 +471,7 @@ test_expect_success 'tag with NUL in header' ' tag=$(git hash-object --literally -t tag -w --stdin <tag-NUL-header) && test_when_finished "remove_object $tag" && - echo $tag >.git/refs/tags/wrong && + git update-ref refs/tags/wrong $tag && test_when_finished "git update-ref -d refs/tags/wrong" && test_must_fail git fsck --tags 2>out && test_grep "error in tag $tag.*unterminated header: NUL at offset" out diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 3f9e7f62e4..a669e592f1 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -208,6 +208,23 @@ test_expect_success 'rev-parse --show-object-format in repo' ' grep "unknown mode for --show-object-format: squeamish-ossifrage" err ' +test_expect_success 'rev-parse --show-ref-format' ' + test_detect_ref_format >expect && + git rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'rev-parse --show-ref-format with invalid storage' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config extensions.refstorage broken && + test_must_fail git rev-parse --show-ref-format 2>err && + grep "error: invalid value for ${SQ}extensions.refstorage${SQ}: ${SQ}broken${SQ}" err + ) +' + test_expect_success '--show-toplevel from subdir of working tree' ' pwd >expect && git -C sub/dir rev-parse --show-toplevel >actual && diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh index bc136833c1..79df65ec7f 100755 --- a/t/t1503-rev-parse-verify.sh +++ b/t/t1503-rev-parse-verify.sh @@ -144,11 +144,6 @@ test_expect_success 'main@{n} for various n' ' test_must_fail git rev-parse --verify main@{$Np1} ' -test_expect_success SYMLINKS,REFFILES 'ref resolution not confused by broken symlinks' ' - ln -s does-not-exist .git/refs/heads/broken && - test_must_fail git rev-parse --verify broken -' - test_expect_success 'options can appear after --verify' ' git rev-parse --verify HEAD >expect && git rev-parse --verify -q HEAD >actual && diff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh index d9997e7b6b..04f53b1ea1 100755 --- a/t/t2011-checkout-invalid-head.sh +++ b/t/t2011-checkout-invalid-head.sh @@ -18,12 +18,12 @@ test_expect_success 'checkout should not start branch from a tree' ' test_must_fail git checkout -b newbranch main^{tree} ' -test_expect_success 'checkout main from invalid HEAD' ' +test_expect_success REFFILES 'checkout main from invalid HEAD' ' echo $ZERO_OID >.git/HEAD && git checkout main -- ' -test_expect_success 'checkout notices failure to lock HEAD' ' +test_expect_success REFFILES 'checkout notices failure to lock HEAD' ' test_when_finished "rm -f .git/HEAD.lock" && >.git/HEAD.lock && test_must_fail git checkout -b other @@ -31,11 +31,8 @@ test_expect_success 'checkout notices failure to lock HEAD' ' test_expect_success 'create ref directory/file conflict scenario' ' git update-ref refs/heads/outer/inner main && - - # do not rely on symbolic-ref to get a known state, - # as it may use the same code we are testing reset_to_df () { - echo "ref: refs/heads/outer" >.git/HEAD + git symbolic-ref HEAD refs/heads/outer } ' diff --git a/t/t2016-checkout-patch.sh b/t/t2016-checkout-patch.sh index 747eb5563e..c4f9bf09aa 100755 --- a/t/t2016-checkout-patch.sh +++ b/t/t2016-checkout-patch.sh @@ -38,26 +38,32 @@ test_expect_success 'git checkout -p with staged changes' ' verify_state dir/foo index index ' -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 '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 '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 && - verify_saved_state bar && - verify_state dir/foo head head -' +for opt in "HEAD" "@" +do + test_expect_success "git checkout -p $opt with NO staged changes: abort" ' + set_and_save_state dir/foo work head && + test_write_lines n y n | git checkout -p $opt >output && + verify_saved_state bar && + verify_saved_state dir/foo && + test_grep "Discard" output + ' + + test_expect_success "git checkout -p $opt with NO staged changes: apply" ' + test_write_lines n y y | git checkout -p $opt >output && + verify_saved_state bar && + verify_state dir/foo head head && + test_grep "Discard" output + ' + + test_expect_success "git checkout -p $opt 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 $opt >output && + verify_saved_state bar && + verify_state dir/foo head head && + test_grep "Discard" output + ' +done test_expect_success 'git checkout -p HEAD^...' ' # the third n is to get out in case it mistakenly does not apply diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh index 947d1587ac..a5c7358eea 100755 --- a/t/t2017-checkout-orphan.sh +++ b/t/t2017-checkout-orphan.sh @@ -86,7 +86,7 @@ test_expect_success '--orphan makes reflog by default' ' git rev-parse --verify delta@{0} ' -test_expect_success REFFILES '--orphan does not make reflog when core.logAllRefUpdates = false' ' +test_expect_success '--orphan does not make reflog when core.logAllRefUpdates = false' ' git checkout main && git config core.logAllRefUpdates false && git checkout --orphan epsilon && diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh index 8202ef8c74..bce284c297 100755 --- a/t/t2020-checkout-detach.sh +++ b/t/t2020-checkout-detach.sh @@ -45,6 +45,18 @@ test_expect_success 'checkout branch does not detach' ' check_not_detached ' +for opt in "HEAD" "@" +do + test_expect_success "checkout $opt no-op/don't detach" ' + reset && + cat .git/HEAD >expect && + git checkout $opt && + cat .git/HEAD >actual && + check_not_detached && + test_cmp expect actual + ' +done + test_expect_success 'checkout tag detaches' ' reset && git checkout tag && diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh index a97416ce65..a3b1449ef1 100755 --- a/t/t2024-checkout-dwim.sh +++ b/t/t2024-checkout-dwim.sh @@ -113,7 +113,7 @@ test_expect_success 'checkout of branch from multiple remotes fails with advice' test_grep ! "^hint: " stderr ' -test_expect_success PERL 'checkout -p with multiple remotes does not print advice' ' +test_expect_success 'checkout -p with multiple remotes does not print advice' ' git checkout -B main && test_might_fail git branch -D foo && diff --git a/t/t2060-switch.sh b/t/t2060-switch.sh index e247a4735b..c91c4db936 100755 --- a/t/t2060-switch.sh +++ b/t/t2060-switch.sh @@ -170,8 +170,10 @@ test_expect_success 'switch back when temporarily detached and checked out elsew # we test in both worktrees to ensure that works # as expected with "first" and "next" worktrees test_must_fail git -C wt1 switch shared && + test_must_fail git -C wt1 switch -C shared && git -C wt1 switch --ignore-other-worktrees shared && test_must_fail git -C wt2 switch shared && + test_must_fail git -C wt2 switch -C shared && git -C wt2 switch --ignore-other-worktrees shared ' diff --git a/t/t2071-restore-patch.sh b/t/t2071-restore-patch.sh index b5c5c0ff7e..27e85be40a 100755 --- a/t/t2071-restore-patch.sh +++ b/t/t2071-restore-patch.sh @@ -4,7 +4,7 @@ test_description='git restore --patch' . ./lib-patch-mode.sh -test_expect_success PERL 'setup' ' +test_expect_success 'setup' ' mkdir dir && echo parent >dir/foo && echo dummy >bar && @@ -16,43 +16,47 @@ test_expect_success PERL 'setup' ' save_head ' -test_expect_success PERL 'restore -p without pathspec is fine' ' +test_expect_success 'restore -p without pathspec is fine' ' echo q >cmd && git restore -p <cmd ' # note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar' -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 restore -p && verify_saved_state bar && verify_saved_state dir/foo ' -test_expect_success PERL 'git restore -p' ' +test_expect_success 'git restore -p' ' set_and_save_state dir/foo work head && test_write_lines n y | git restore -p && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success PERL 'git restore -p with staged changes' ' +test_expect_success 'git restore -p with staged changes' ' set_state dir/foo work index && test_write_lines n y | git restore -p && verify_saved_state bar && verify_state dir/foo index index ' -test_expect_success PERL 'git restore -p --source=HEAD' ' - set_state dir/foo work index && - # the third n is to get out in case it mistakenly does not apply - test_write_lines n y n | git restore -p --source=HEAD && - verify_saved_state bar && - verify_state dir/foo head index -' - -test_expect_success PERL 'git restore -p --source=HEAD^' ' +for opt in "HEAD" "@" +do + test_expect_success "git restore -p --source=$opt" ' + set_state dir/foo work index && + # the third n is to get out in case it mistakenly does not apply + test_write_lines n y n | git restore -p --source=$opt >output && + verify_saved_state bar && + verify_state dir/foo head index && + test_grep "Discard" output + ' +done + +test_expect_success 'git restore -p --source=HEAD^' ' set_state dir/foo work index && # the third n is to get out in case it mistakenly does not apply test_write_lines n y n | git restore -p --source=HEAD^ && @@ -60,7 +64,7 @@ test_expect_success PERL 'git restore -p --source=HEAD^' ' verify_state dir/foo parent index ' -test_expect_success PERL 'git restore -p --source=HEAD^...' ' +test_expect_success 'git restore -p --source=HEAD^...' ' set_state dir/foo work index && # the third n is to get out in case it mistakenly does not apply test_write_lines n y n | git restore -p --source=HEAD^... && @@ -68,7 +72,7 @@ test_expect_success PERL 'git restore -p --source=HEAD^...' ' verify_state dir/foo parent index ' -test_expect_success PERL 'git restore -p handles deletion' ' +test_expect_success 'git restore -p handles deletion' ' set_state dir/foo work index && rm dir/foo && test_write_lines n y | git restore -p && @@ -81,21 +85,21 @@ test_expect_success PERL 'git restore -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 restore -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 restore -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' ' 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 | git restore -p --source=HEAD^ -- dir && @@ -103,7 +107,7 @@ test_expect_success PERL 'path limiting works: HEAD^ -- dir' ' verify_state dir/foo parent head ' -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 restore -p foo) && @@ -111,7 +115,7 @@ 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 ' diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh index df4aff7825..c28c04133c 100755 --- a/t/t2400-worktree-add.sh +++ b/t/t2400-worktree-add.sh @@ -126,6 +126,28 @@ test_expect_success 'die the same branch is already checked out' ' ) ' +test_expect_success 'refuse to reset a branch in use elsewhere' ' + ( + cd here && + + # we know we are on detached HEAD but just in case ... + git checkout --detach HEAD && + git rev-parse --verify HEAD >old.head && + + git rev-parse --verify refs/heads/newmain >old.branch && + test_must_fail git checkout -B newmain 2>error && + git rev-parse --verify refs/heads/newmain >new.branch && + git rev-parse --verify HEAD >new.head && + + grep "already used by worktree at" error && + test_cmp old.branch new.branch && + test_cmp old.head new.head && + + # and we must be still on the same detached HEAD state + test_must_fail git symbolic-ref HEAD + ) +' + test_expect_success SYMLINKS 'die the same branch is already checked out (symlink)' ' head=$(git -C there rev-parse --git-path HEAD) && ref=$(git -C there symbolic-ref HEAD) && @@ -415,7 +437,7 @@ test_wt_add_orphan_hint () { git -C repo switch --orphan noref && test_must_fail git -C repo worktree add $opts foobar/ 2>actual && ! grep "error: unknown switch" actual && - grep "hint: If you meant to create a worktree containing a new orphan branch" actual && + grep "hint: If you meant to create a worktree containing a new unborn branch" actual && if [ $use_branch -eq 1 ] then grep -E "^hint: +git worktree add --orphan -b [^ ]+ [^ ]+$" actual @@ -436,7 +458,7 @@ test_expect_success "'worktree add' doesn't show orphan hint in bad/orphan HEAD (cd repo && test_commit commit) && test_must_fail git -C repo worktree add --quiet foobar_branch foobar/ 2>actual && ! grep "error: unknown switch" actual && - ! grep "hint: If you meant to create a worktree containing a new orphan branch" actual + ! grep "hint: If you meant to create a worktree containing a new unborn branch" actual ' test_expect_success 'local clone from linked checkout' ' @@ -468,7 +490,8 @@ test_expect_success 'put a worktree under rebase' ' cd under-rebase && set_fake_editor && FAKE_LINES="edit 1" git rebase -i HEAD^ && - git worktree list | grep "under-rebase.*detached HEAD" + git worktree list >actual && + grep "under-rebase.*detached HEAD" actual ) ' @@ -509,7 +532,8 @@ test_expect_success 'checkout a branch under bisect' ' git bisect start && git bisect bad && git bisect good HEAD~2 && - git worktree list | grep "under-bisect.*detached HEAD" && + git worktree list >actual && + grep "under-bisect.*detached HEAD" actual && test_must_fail git worktree add new-bisect under-bisect && ! test -d new-bisect ) @@ -709,9 +733,9 @@ test_expect_success 'git worktree --no-guess-remote option overrides config' ' test_dwim_orphan () { local info_text="No possible source branch, inferring '--orphan'" && local fetch_error_text="fatal: No local or remote refs exist despite at least one remote" && - local orphan_hint="hint: If you meant to create a worktree containing a new orphan branch" && + local orphan_hint="hint: If you meant to create a worktree containing a new unborn branch" && local invalid_ref_regex="^fatal: invalid reference: " && - local bad_combo_regex="^fatal: '[-a-z]*' and '[-a-z]*' cannot be used together" && + local bad_combo_regex="^fatal: options '[-a-z]*' and '[-a-z]*' cannot be used together" && local git_ns="repo" && local dashc_args="-C $git_ns" && diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index c54fd9ea06..e36f4d15f2 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -28,7 +28,7 @@ test_expect_success 'git branch --help should not have created a bogus branch' ' test_ref_missing refs/heads/--help ' -test_expect_success 'branch -h in broken repository' ' +test_expect_success REFFILES 'branch -h in broken repository' ' mkdir broken && ( cd broken && @@ -76,14 +76,14 @@ test_expect_success 'git branch HEAD should fail' ' ' cat >expect <<EOF -$ZERO_OID $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from main +$HEAD refs/heads/d/e/f@{0}: branch: Created from main EOF test_expect_success 'git branch --create-reflog d/e/f should create a branch and a log' ' GIT_COMMITTER_DATE="2005-05-26 23:30" \ git -c core.logallrefupdates=false branch --create-reflog d/e/f && test_ref_exists refs/heads/d/e/f && - test_path_is_file .git/logs/refs/heads/d/e/f && - test_cmp expect .git/logs/refs/heads/d/e/f + git reflog show --no-abbrev-commit refs/heads/d/e/f >actual && + test_cmp expect actual ' test_expect_success 'git branch -d d/e/f should delete a branch and a log' ' @@ -203,10 +203,9 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou test $(git rev-parse --abbrev-ref HEAD) = bam ' -test_expect_success 'git branch -M baz bam should add entries to .git/logs/HEAD' ' - msg="Branch: renamed refs/heads/baz to refs/heads/bam" && - grep " $ZERO_OID.*$msg$" .git/logs/HEAD && - grep "^$ZERO_OID.*$msg$" .git/logs/HEAD +test_expect_success 'git branch -M baz bam should add entries to HEAD reflog' ' + git reflog show HEAD >actual && + grep "HEAD@{0}: Branch: renamed refs/heads/baz to refs/heads/bam" actual ' test_expect_success 'git branch -M should leave orphaned HEAD alone' ' @@ -215,17 +214,20 @@ test_expect_success 'git branch -M should leave orphaned HEAD alone' ' cd orphan && test_commit initial && git checkout --orphan lonely && - grep lonely .git/HEAD && + git symbolic-ref HEAD >expect && + echo refs/heads/lonely >actual && + test_cmp expect actual && test_ref_missing refs/head/lonely && git branch -M main mistress && - grep lonely .git/HEAD + git symbolic-ref HEAD >expect && + test_cmp expect actual ) ' test_expect_success 'resulting reflog can be shown by log -g' ' oid=$(git rev-parse HEAD) && cat >expect <<-EOF && - HEAD@{0} $oid $msg + HEAD@{0} $oid Branch: renamed refs/heads/baz to refs/heads/bam HEAD@{2} $oid checkout: moving from foo to baz EOF git log -g --format="%gd %H %gs" -2 HEAD >actual && @@ -243,7 +245,7 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou git worktree prune ' -test_expect_success 'git branch -M fails if updating any linked working tree fails' ' +test_expect_success REFFILES 'git branch -M fails if updating any linked working tree fails' ' git worktree add -b baz bazdir1 && git worktree add -f bazdir2 baz && touch .git/worktrees/bazdir1/HEAD.lock && @@ -517,7 +519,7 @@ EOF mv .git/config .git/config-saved -test_expect_success SHA1 'git branch -m q q2 without config should succeed' ' +test_expect_success DEFAULT_REPO_FORMAT 'git branch -m q q2 without config should succeed' ' git branch -m q q2 && git branch -m q2 q ' @@ -699,7 +701,8 @@ test_expect_success 'git branch -C c1 c2 should succeed when c1 is checked out' test_expect_success 'git branch -C c1 c2 should never touch HEAD' ' msg="Branch: copied refs/heads/c1 to refs/heads/c2" && - ! grep "$msg$" .git/logs/HEAD + git reflog HEAD >actual && + ! grep "$msg$" actual ' test_expect_success 'git branch -C main should work when main is checked out' ' @@ -809,7 +812,7 @@ test_expect_success 'deleting a symref' ' test_expect_success 'deleting a dangling symref' ' git symbolic-ref refs/heads/dangling-symref nowhere && - test_path_is_file .git/refs/heads/dangling-symref && + git symbolic-ref --no-recurse refs/heads/dangling-symref && echo "Deleted branch dangling-symref (was nowhere)." >expect && git branch -d dangling-symref >actual && test_ref_missing refs/heads/dangling-symref && @@ -833,35 +836,6 @@ test_expect_success 'renaming a symref is not allowed' ' test_ref_missing refs/heads/new-topic ' -test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for u is a symlink' ' - git branch --create-reflog u && - mv .git/logs/refs/heads/u real-u && - ln -s real-u .git/logs/refs/heads/u && - test_must_fail git branch -m u v -' - -test_expect_success SYMLINKS 'git branch -m with symlinked .git/refs' ' - test_when_finished "rm -rf subdir" && - git init --bare subdir && - - rm -rfv subdir/refs subdir/objects subdir/packed-refs && - ln -s ../.git/refs subdir/refs && - ln -s ../.git/objects subdir/objects && - ln -s ../.git/packed-refs subdir/packed-refs && - - git -C subdir rev-parse --absolute-git-dir >subdir.dir && - git rev-parse --absolute-git-dir >our.dir && - ! test_cmp subdir.dir our.dir && - - git -C subdir log && - git -C subdir branch rename-src && - git rev-parse rename-src >expect && - git -C subdir branch -m rename-src rename-dest && - git rev-parse rename-dest >actual && - test_cmp expect actual && - git branch -D rename-dest -' - test_expect_success 'test tracking setup via --track' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && @@ -1140,14 +1114,14 @@ test_expect_success '--set-upstream-to notices an error to set branch as own ups # Keep this test last, as it changes the current branch cat >expect <<EOF -$ZERO_OID $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from main +$HEAD refs/heads/g/h/i@{0}: branch: Created from main EOF test_expect_success 'git checkout -b g/h/i -l should create a branch and a log' ' GIT_COMMITTER_DATE="2005-05-26 23:30" \ git checkout -b g/h/i -l main && test_ref_exists refs/heads/g/h/i && - test_path_is_file .git/logs/refs/heads/g/h/i && - test_cmp expect .git/logs/refs/heads/g/h/i + git reflog show --no-abbrev-commit refs/heads/g/h/i >actual && + test_cmp expect actual ' test_expect_success 'checkout -b makes reflog by default' ' @@ -1573,9 +1547,10 @@ test_expect_success 'tracking with unexpected .fetch refspec' ' test_expect_success 'configured committerdate sort' ' git init -b main sort && + test_config -C sort branch.sort "committerdate" && + ( cd sort && - git config branch.sort committerdate && test_commit initial && git checkout -b a && test_commit a && @@ -1595,9 +1570,10 @@ test_expect_success 'configured committerdate sort' ' ' test_expect_success 'option override configured sort' ' + test_config -C sort branch.sort "committerdate" && + ( cd sort && - git config branch.sort committerdate && git branch --sort=refname >actual && cat >expect <<-\EOF && a @@ -1609,10 +1585,70 @@ test_expect_success 'option override configured sort' ' ) ' +test_expect_success '--no-sort cancels config sort keys' ' + test_config -C sort branch.sort "-refname" && + + ( + cd sort && + + # objecttype is identical for all of them, so sort falls back on + # default (ascending refname) + git branch \ + --no-sort \ + --sort="objecttype" >actual && + cat >expect <<-\EOF && + a + * b + c + main + EOF + test_cmp expect actual + ) + +' + +test_expect_success '--no-sort cancels command line sort keys' ' + ( + cd sort && + + # objecttype is identical for all of them, so sort falls back on + # default (ascending refname) + git branch \ + --sort="-refname" \ + --no-sort \ + --sort="objecttype" >actual && + cat >expect <<-\EOF && + a + * b + c + main + EOF + test_cmp expect actual + ) +' + +test_expect_success '--no-sort without subsequent --sort prints expected branches' ' + ( + cd sort && + + # Sort the results with `sort` for a consistent comparison + # against expected + git branch --no-sort | sort >actual && + cat >expect <<-\EOF && + a + c + main + * b + EOF + test_cmp expect actual + ) +' + test_expect_success 'invalid sort parameter in configuration' ' + test_config -C sort branch.sort "v:notvalid" && + ( cd sort && - git config branch.sort "v:notvalid" && # this works in the "listing" mode, so bad sort key # is a dying offence. diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh index 6a98b2df76..a1139f79e2 100755 --- a/t/t3202-show-branch.sh +++ b/t/t3202-show-branch.sh @@ -4,9 +4,6 @@ test_description='test show-branch' . ./test-lib.sh -# arbitrary reference time: 2009-08-30 19:20:00 -GIT_TEST_DATE_NOW=1251660000; export GIT_TEST_DATE_NOW - test_expect_success 'error descriptions on empty repository' ' current=$(git branch --show-current) && cat >expect <<-EOF && @@ -187,18 +184,6 @@ test_expect_success 'show branch --merge-base with N arguments' ' test_cmp expect actual ' -test_expect_success 'show branch --reflog=2' ' - sed "s/^> //" >expect <<-\EOF && - > ! [refs/heads/branch10@{0}] (4 years, 5 months ago) commit: branch10 - > ! [refs/heads/branch10@{1}] (4 years, 5 months ago) commit: branch10 - > -- - > + [refs/heads/branch10@{0}] branch10 - > ++ [refs/heads/branch10@{1}] initial - EOF - git show-branch --reflog=2 >actual && - test_cmp actual expect -' - # incompatible options while read combo do @@ -264,4 +249,38 @@ test_expect_success 'error descriptions on orphan branch' ' test_branch_op_in_wt -c new-branch ' +test_expect_success 'setup reflogs' ' + test_commit base && + git checkout -b branch && + test_commit one && + git reset --hard HEAD^ && + test_commit two && + test_commit three +' + +test_expect_success '--reflog shows reflog entries' ' + cat >expect <<-\EOF && + ! [branch@{0}] (0 seconds ago) commit: three + ! [branch@{1}] (60 seconds ago) commit: two + ! [branch@{2}] (2 minutes ago) reset: moving to HEAD^ + ! [branch@{3}] (2 minutes ago) commit: one + ---- + + [branch@{0}] three + ++ [branch@{1}] two + + [branch@{3}] one + ++++ [branch@{2}] base + EOF + # the output always contains relative timestamps; use + # a known time to get deterministic results + GIT_TEST_DATE_NOW=$test_tick \ + git show-branch --reflog branch >actual && + test_cmp expect actual +' + +test_expect_success '--reflog handles missing reflog' ' + git reflog expire --expire=now branch && + git show-branch --reflog branch >actual && + test_must_be_empty actual +' + test_done diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh index 60d6ed2dc8..597df5ebc0 100755 --- a/t/t3310-notes-merge-manual-resolve.sh +++ b/t/t3310-notes-merge-manual-resolve.sh @@ -561,9 +561,9 @@ y and z notes on 4th commit EOF # Fail to finalize merge test_must_fail git notes merge --commit >output 2>&1 && - # .git/NOTES_MERGE_* must remain - test -f .git/NOTES_MERGE_PARTIAL && - test -f .git/NOTES_MERGE_REF && + # NOTES_MERGE_* refs and .git/NOTES_MERGE_* state files must remain + git rev-parse --verify NOTES_MERGE_PARTIAL && + git rev-parse --verify NOTES_MERGE_REF && test -f .git/NOTES_MERGE_WORKTREE/$commit_sha1 && test -f .git/NOTES_MERGE_WORKTREE/$commit_sha2 && test -f .git/NOTES_MERGE_WORKTREE/$commit_sha3 && diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 24a539c662..e1c8c5f701 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -424,16 +424,6 @@ test_expect_success 'refuse to switch to branch checked out elsewhere' ' test_grep "already used by worktree at" err ' -test_expect_success MINGW,SYMLINKS_WINDOWS 'rebase when .git/logs is a symlink' ' - git checkout main && - mv .git/logs actual_logs && - cmd //c "mklink /D .git\logs ..\actual_logs" && - git rebase -f HEAD^ && - test -L .git/logs && - rm .git/logs && - mv actual_logs .git/logs -' - test_expect_success 'rebase when inside worktree subdirectory' ' git init main-wt && ( diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index c5f30554c6..d1bead61fa 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -153,6 +153,18 @@ test_expect_success 'rebase -i with the exec command checks tree cleanness' ' git rebase --continue ' +test_expect_success 'cherry-pick works with rebase --exec' ' + test_when_finished "git cherry-pick --abort; \ + git rebase --abort; \ + git checkout primary" && + echo "exec git cherry-pick G" >todo && + ( + set_replace_editor todo && + test_must_fail git rebase -i D D + ) && + test_cmp_rev G CHERRY_PICK_HEAD +' + test_expect_success 'rebase -x with empty command fails' ' test_when_finished "git rebase --abort ||:" && test_must_fail env git rebase -x "" @ 2>actual && @@ -2160,7 +2172,7 @@ test_expect_success '--update-refs: check failed ref update' ' # recorded in the update-refs file. We will force-update the # "second" ref, but "git branch -f" will not work because of # the lock in the update-refs file. - git rev-parse third >.git/refs/heads/second && + git update-ref refs/heads/second third && test_must_fail git rebase --continue 2>err && grep "update_ref failed for ref '\''refs/heads/second'\''" err && diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh index ebbaed147a..9f49c4228b 100755 --- a/t/t3407-rebase-abort.sh +++ b/t/t3407-rebase-abort.sh @@ -40,9 +40,24 @@ testrebase() { test_path_is_missing "$state_dir" ' + test_expect_success "pre rebase$type head is marked as reachable" ' + # Clean up the state from the previous one + git checkout -f --detach pre-rebase && + test_tick && + git commit --amend --only -m "reworded" && + orig_head=$(git rev-parse HEAD) && + test_must_fail git rebase$type main && + # Stop ORIG_HEAD marking $state_dir/orig-head as reachable + git update-ref -d ORIG_HEAD && + git reflog expire --expire="$GIT_COMMITTER_DATE" --all && + git prune --expire=now && + git rebase --abort && + test_cmp_rev $orig_head HEAD + ' + test_expect_success "rebase$type --abort after --skip" ' # Clean up the state from the previous one - git reset --hard pre-rebase && + git checkout -B to-rebase pre-rebase && test_must_fail git rebase$type main && test_path_is_dir "$state_dir" && test_must_fail git rebase --skip && diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh index 693934ee8b..1a820f1481 100755 --- a/t/t3420-rebase-autostash.sh +++ b/t/t3420-rebase-autostash.sh @@ -333,4 +333,14 @@ test_expect_success 'never change active branch' ' test_cmp_rev not-the-feature-branch unrelated-onto-branch ' +test_expect_success 'autostash commit is marked as reachable' ' + echo changed >file0 && + git rebase --autostash --exec "git prune --expire=now" \ + feature-branch^ feature-branch && + # git rebase succeeds if the stash cannot be applied so we need to check + # the contents of file0 + echo changed >expect && + test_cmp expect file0 +' + test_done diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh new file mode 100755 index 0000000000..389670262e --- /dev/null +++ b/t/t3650-replay-basics.sh @@ -0,0 +1,198 @@ +#!/bin/sh + +test_description='basic git replay tests' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh + +GIT_AUTHOR_NAME=author@name +GIT_AUTHOR_EMAIL=bogus@email@address +export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL + +test_expect_success 'setup' ' + test_commit A && + test_commit B && + + git switch -c topic1 && + test_commit C && + git switch -c topic2 && + test_commit D && + test_commit E && + git switch topic1 && + test_commit F && + git switch -c topic3 && + test_commit G && + test_commit H && + git switch -c topic4 main && + test_commit I && + test_commit J && + + git switch -c next main && + test_commit K && + git merge -m "Merge topic1" topic1 && + git merge -m "Merge topic2" topic2 && + git merge -m "Merge topic3" topic3 && + >evil && + git add evil && + git commit --amend && + git merge -m "Merge topic4" topic4 && + + git switch main && + test_commit L && + test_commit M && + + git switch -c conflict B && + test_commit C.conflict C.t conflict +' + +test_expect_success 'setup bare' ' + git clone --bare . bare +' + +test_expect_success 'using replay to rebase two branches, one on top of other' ' + git replay --onto main topic1..topic2 >result && + + test_line_count = 1 result && + + git log --format=%s $(cut -f 3 -d " " result) >actual && + test_write_lines E D M L B A >expect && + test_cmp expect actual && + + printf "update refs/heads/topic2 " >expect && + printf "%s " $(cut -f 3 -d " " result) >>expect && + git rev-parse topic2 >>expect && + + test_cmp expect result +' + +test_expect_success 'using replay on bare repo to rebase two branches, one on top of other' ' + git -C bare replay --onto main topic1..topic2 >result-bare && + test_cmp expect result-bare +' + +test_expect_success 'using replay to rebase with a conflict' ' + test_expect_code 1 git replay --onto topic1 B..conflict +' + +test_expect_success 'using replay on bare repo to rebase with a conflict' ' + test_expect_code 1 git -C bare replay --onto topic1 B..conflict +' + +test_expect_success 'using replay to perform basic cherry-pick' ' + # The differences between this test and previous ones are: + # --advance vs --onto + # 2nd field of result is refs/heads/main vs. refs/heads/topic2 + # 4th field of result is hash for main instead of hash for topic2 + + git replay --advance main topic1..topic2 >result && + + test_line_count = 1 result && + + git log --format=%s $(cut -f 3 -d " " result) >actual && + test_write_lines E D M L B A >expect && + test_cmp expect actual && + + printf "update refs/heads/main " >expect && + printf "%s " $(cut -f 3 -d " " result) >>expect && + git rev-parse main >>expect && + + test_cmp expect result +' + +test_expect_success 'using replay on bare repo to perform basic cherry-pick' ' + git -C bare replay --advance main topic1..topic2 >result-bare && + test_cmp expect result-bare +' + +test_expect_success 'replay on bare repo fails with both --advance and --onto' ' + test_must_fail git -C bare replay --advance main --onto main topic1..topic2 >result-bare +' + +test_expect_success 'replay fails when both --advance and --onto are omitted' ' + test_must_fail git replay topic1..topic2 >result +' + +test_expect_success 'using replay to also rebase a contained branch' ' + git replay --contained --onto main main..topic3 >result && + + test_line_count = 2 result && + cut -f 3 -d " " result >new-branch-tips && + + git log --format=%s $(head -n 1 new-branch-tips) >actual && + test_write_lines F C M L B A >expect && + test_cmp expect actual && + + git log --format=%s $(tail -n 1 new-branch-tips) >actual && + test_write_lines H G F C M L B A >expect && + test_cmp expect actual && + + printf "update refs/heads/topic1 " >expect && + printf "%s " $(head -n 1 new-branch-tips) >>expect && + git rev-parse topic1 >>expect && + printf "update refs/heads/topic3 " >>expect && + printf "%s " $(tail -n 1 new-branch-tips) >>expect && + git rev-parse topic3 >>expect && + + test_cmp expect result +' + +test_expect_success 'using replay on bare repo to also rebase a contained branch' ' + git -C bare replay --contained --onto main main..topic3 >result-bare && + test_cmp expect result-bare +' + +test_expect_success 'using replay to rebase multiple divergent branches' ' + git replay --onto main ^topic1 topic2 topic4 >result && + + test_line_count = 2 result && + cut -f 3 -d " " result >new-branch-tips && + + git log --format=%s $(head -n 1 new-branch-tips) >actual && + test_write_lines E D M L B A >expect && + test_cmp expect actual && + + git log --format=%s $(tail -n 1 new-branch-tips) >actual && + test_write_lines J I M L B A >expect && + test_cmp expect actual && + + printf "update refs/heads/topic2 " >expect && + printf "%s " $(head -n 1 new-branch-tips) >>expect && + git rev-parse topic2 >>expect && + printf "update refs/heads/topic4 " >>expect && + printf "%s " $(tail -n 1 new-branch-tips) >>expect && + git rev-parse topic4 >>expect && + + test_cmp expect result +' + +test_expect_success 'using replay on bare repo to rebase multiple divergent branches, including contained ones' ' + git -C bare replay --contained --onto main ^main topic2 topic3 topic4 >result && + + test_line_count = 4 result && + cut -f 3 -d " " result >new-branch-tips && + + >expect && + for i in 2 1 3 4 + do + printf "update refs/heads/topic$i " >>expect && + printf "%s " $(grep topic$i result | cut -f 3 -d " ") >>expect && + git -C bare rev-parse topic$i >>expect || return 1 + done && + + test_cmp expect result && + + test_write_lines F C M L B A >expect1 && + test_write_lines E D C M L B A >expect2 && + test_write_lines H G F C M L B A >expect3 && + test_write_lines J I M L B A >expect4 && + + for i in 1 2 3 4 + do + git -C bare log --format=%s $(grep topic$i result | cut -f 3 -d " ") >actual && + test_cmp expect$i actual || return 1 + done +' + +test_done diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 34faeac3f1..00db82fb24 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -200,7 +200,7 @@ test_expect_success 'drop stash reflog updates refs/stash' ' test_cmp expect actual ' -test_expect_success REFFILES 'drop stash reflog updates refs/stash with rewrite' ' +test_expect_success 'drop stash reflog updates refs/stash with rewrite' ' git init repo && ( cd repo && @@ -213,16 +213,16 @@ test_expect_success REFFILES 'drop stash reflog updates refs/stash with rewrite' new_oid="$(git -C repo rev-parse stash@{0})" && cat >expect <<-EOF && - $(test_oid zero) $old_oid - $old_oid $new_oid + $new_oid + $old_oid EOF - cut -d" " -f1-2 repo/.git/logs/refs/stash >actual && + git -C repo reflog show refs/stash --format=%H >actual && test_cmp expect actual && git -C repo stash drop stash@{1} && - cut -d" " -f1-2 repo/.git/logs/refs/stash >actual && + git -C repo reflog show refs/stash --format=%H >actual && cat >expect <<-EOF && - $(test_oid zero) $new_oid + $new_oid EOF test_cmp expect actual ' @@ -1516,4 +1516,56 @@ test_expect_success 'restore untracked files even when we hit conflicts' ' ) ' +test_expect_success 'stash create reports a locked index' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit A A.file && + echo change >A.file && + touch .git/index.lock && + + cat >expect <<-EOF && + error: could not write index + EOF + test_must_fail git stash create 2>err && + test_cmp expect err + ) +' + +test_expect_success 'stash push reports a locked index' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit A A.file && + echo change >A.file && + touch .git/index.lock && + + cat >expect <<-EOF && + error: could not write index + EOF + test_must_fail git stash push 2>err && + test_cmp expect err + ) +' + +test_expect_success 'stash apply reports a locked index' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit A A.file && + echo change >A.file && + git stash push && + touch .git/index.lock && + + cat >expect <<-EOF && + error: could not write index + EOF + test_must_fail git stash apply 2>err && + test_cmp expect err + ) +' + test_done diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh index accfe3845c..368fc2a6cc 100755 --- a/t/t3904-stash-patch.sh +++ b/t/t3904-stash-patch.sh @@ -3,12 +3,6 @@ test_description='stash -p' . ./lib-patch-mode.sh -if ! test_have_prereq PERL -then - skip_all='skipping stash -p tests, perl not available' - test_done -fi - test_expect_success 'setup' ' mkdir dir && echo parent > dir/foo && diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index 85be1367de..49c042a38a 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -286,4 +286,28 @@ test_expect_success 'basename similarity vs best similarity' ' test_cmp expected actual ' +test_expect_success 'last line matters too' ' + { + test_write_lines a 0 1 2 3 4 5 6 7 8 9 && + printf "git ignores final up to 63 characters if not newline terminated" + } >no-final-lf && + git add no-final-lf && + git commit -m "original version of file with no final newline" && + + # Change ONLY the first character of the whole file + { + test_write_lines b 0 1 2 3 4 5 6 7 8 9 && + printf "git ignores final up to 63 characters if not newline terminated" + } >no-final-lf && + git add no-final-lf && + git mv no-final-lf still-absent-final-lf && + git commit -a -m "rename no-final-lf -> still-absent-final-lf" && + git diff-tree -r -M --name-status HEAD^ HEAD >actual && + sed -e "s/^R[0-9]* /R /" actual >actual.munged && + cat >expected <<-\EOF && + R no-final-lf still-absent-final-lf + EOF + test_cmp expected actual.munged +' + test_done diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 5cc17c2e0d..1e3b2dbea4 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -178,32 +178,29 @@ process_diffs () { V=$(git version | sed -e 's/^git version //' -e 's/\./\\./g') while read magic cmd do - status=success case "$magic" in '' | '#'*) continue ;; - :*) - magic=${magic#:} + :noellipses) + magic=noellipses label="$magic-$cmd" - case "$magic" in - noellipses) ;; - failure) - status=failure - magic= - label="$cmd" ;; - *) - BUG "unknown magic $magic" ;; - esac ;; + ;; + :*) + BUG "unknown magic $magic" + ;; *) - cmd="$magic $cmd" magic= - label="$cmd" ;; + cmd="$magic $cmd" + magic= + label="$cmd" + ;; esac + test=$(echo "$label" | sed -e 's|[/ ][/ ]*|_|g') pfx=$(printf "%04d" $test_count) expect="$TEST_DIRECTORY/t4013/diff.$test" actual="$pfx-diff.$test" - test_expect_$status "git $cmd # magic is ${magic:-(not used)}" ' + test_expect_success "git $cmd # magic is ${magic:-(not used)}" ' { echo "$ git $cmd" case "$magic" in @@ -522,7 +519,7 @@ test_expect_success 'log -S requires an argument' ' ' test_expect_success 'diff --cached on unborn branch' ' - echo ref: refs/heads/unborn >.git/HEAD && + git symbolic-ref HEAD refs/heads/unborn && git diff --cached >result && process_diffs result >actual && process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--cached" >expected && @@ -666,4 +663,10 @@ test_expect_success 'diff --default-prefix overrides diff.mnemonicprefix' ' check_prefix actual a/file0 b/file0 ' +test_expect_success 'diff --no-renames cannot be abbreviated' ' + test_expect_code 129 git diff --no-rename >actual 2>error && + test_must_be_empty actual && + grep "invalid option: --no-rename" error +' + test_done diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 5ced27ed45..e37a1411ee 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1906,6 +1906,16 @@ body" && grep "^body$" actual ' +test_expect_success 'cover letter with --cover-from-description subject (UTF-8 subject line)' ' + test_config branch.rebuild-1.description "Café? + +body" && + git checkout rebuild-1 && + git format-patch --stdout --cover-letter --cover-from-description subject --encode-email-headers main >actual && + grep "^Subject: \[PATCH 0/2\] =?UTF-8?q?Caf=C3=A9=3F?=$" actual && + ! grep "Café" actual +' + test_expect_success 'cover letter with format.coverFromDescription = auto (short subject line)' ' test_config branch.rebuild-1.description "config subject diff --git a/t/t4042-diff-textconv-caching.sh b/t/t4042-diff-textconv-caching.sh index bf33aedf4b..8ebfa3c1be 100755 --- a/t/t4042-diff-textconv-caching.sh +++ b/t/t4042-diff-textconv-caching.sh @@ -118,4 +118,26 @@ test_expect_success 'log notes cache and still use cache for -p' ' git log --no-walk -p refs/notes/textconv/magic HEAD ' +test_expect_success 'caching is silently ignored outside repo' ' + mkdir -p non-repo && + echo one >non-repo/one && + echo two >non-repo/two && + echo "* diff=test" >attr && + test_expect_code 1 \ + nongit git -c core.attributesFile="$PWD/attr" \ + -c diff.test.textconv="tr a-z A-Z <" \ + -c diff.test.cachetextconv=true \ + diff --no-index one two >actual && + cat >expect <<-\EOF && + diff --git a/one b/two + index 5626abf..f719efd 100644 + --- a/one + +++ b/two + @@ -1 +1 @@ + -ONE + +TWO + EOF + test_cmp expect actual +' + test_done diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 5ce345d309..651ec77660 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -205,6 +205,18 @@ test_expect_success POSIXPERM,SYMLINKS 'diff --no-index normalizes: mode not lik test_cmp expected actual ' +test_expect_success POSIXPERM 'external diff with mode-only change' ' + echo content >not-executable && + echo content >executable && + chmod +x executable && + echo executable executable $(test_oid zero) 100755 \ + not-executable $(test_oid zero) 100644 not-executable \ + >expect && + test_expect_code 1 git -c diff.external=echo diff \ + --no-index executable not-executable >actual && + test_cmp expect actual +' + test_expect_success "diff --no-index treats '-' as stdin" ' cat >expect <<-EOF && diff --git a/- b/a/1 diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index e7a7295f1b..4eb8444029 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -41,7 +41,8 @@ test_expect_success FILEMODE 'same mode (index only)' ' chmod +x file && git add file && git apply --cached patch-0.txt && - git ls-files -s file | grep "^100755" + git ls-files -s file >ls-files-output && + test_grep "^100755" ls-files-output ' test_expect_success FILEMODE 'mode update (no index)' ' @@ -60,7 +61,8 @@ test_expect_success FILEMODE 'mode update (with index)' ' test_expect_success FILEMODE 'mode update (index only)' ' git reset --hard && git apply --cached patch-1.txt && - git ls-files -s file | grep "^100755" + git ls-files -s file >ls-files-output && + test_grep "^100755" ls-files-output ' test_expect_success FILEMODE 'empty mode is rejected' ' @@ -101,4 +103,31 @@ test_expect_success POSIXPERM 'do not use core.sharedRepository for working tree ) ' +test_expect_success 'git apply respects core.fileMode' ' + test_config core.fileMode false && + echo true >script.sh && + git add --chmod=+x script.sh && + git ls-files -s script.sh >ls-files-output && + test_grep "^100755" ls-files-output && + test_tick && git commit -m "Add script" && + git ls-tree -r HEAD script.sh >ls-tree-output && + test_grep "^100755" ls-tree-output && + + echo true >>script.sh && + test_tick && git commit -m "Modify script" script.sh && + git format-patch -1 --stdout >patch && + test_grep "^index.*100755$" patch && + + git switch -c branch HEAD^ && + git apply --index patch 2>err && + test_grep ! "has type 100644, expected 100755" err && + git reset --hard && + + git apply patch 2>err && + test_grep ! "has type 100644, expected 100755" err && + + git apply --cached patch 2>err && + test_grep ! "has type 100644, expected 100755" err +' + test_done diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 708636671a..60fe60d761 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -2255,23 +2255,6 @@ test_expect_success 'log on empty repo fails' ' test_grep does.not.have.any.commits stderr ' -test_expect_success REFFILES 'log diagnoses bogus HEAD hash' ' - git init empty && - test_when_finished "rm -rf empty" && - echo 1234abcd >empty/.git/refs/heads/main && - test_must_fail git -C empty log 2>stderr && - test_grep broken stderr -' - -test_expect_success REFFILES 'log diagnoses bogus HEAD symref' ' - git init empty && - echo "ref: refs/heads/invalid.lock" > empty/.git/HEAD && - test_must_fail git -C empty log 2>stderr && - test_grep broken stderr && - test_must_fail git -C empty log --default totally-bogus 2>stderr && - test_grep broken stderr -' - test_expect_success 'log does not default to HEAD when rev input is given' ' git log --branches=does-not-exist >actual && test_must_be_empty actual diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh index 21986a866d..73ea9e5155 100755 --- a/t/t4207-log-decoration-colors.sh +++ b/t/t4207-log-decoration-colors.sh @@ -70,8 +70,14 @@ ${c_tag}tag: ${c_reset}${c_tag}A${c_reset}${c_commit})${c_reset} A cmp_filtered_decorations ' +remove_replace_refs () { + git for-each-ref 'refs/replace*/**' --format='delete %(refname)' >in && + git update-ref --stdin <in && + rm in +} + test_expect_success 'test coloring with replace-objects' ' - test_when_finished rm -rf .git/refs/replace* && + test_when_finished remove_replace_refs && test_commit C && test_commit D && @@ -99,7 +105,7 @@ EOF ' test_expect_success 'test coloring with grafted commit' ' - test_when_finished rm -rf .git/refs/replace* && + test_when_finished remove_replace_refs && git replace --graft HEAD HEAD~2 && diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh index b2c8a43fce..12ac436873 100755 --- a/t/t4301-merge-tree-write-tree.sh +++ b/t/t4301-merge-tree-write-tree.sh @@ -887,7 +887,7 @@ test_expect_success '--stdin with both a successful and a conflicted merge' ' test_expect_success '--merge-base is incompatible with --stdin' ' test_must_fail git merge-tree --merge-base=side1 --stdin 2>expect && - grep "^fatal: --merge-base is incompatible with --stdin" expect + grep "^fatal: .*merge-base.*stdin.* cannot be used together" expect ' # specify merge-base as parent of branch2 diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index 4b4c3315d8..72b8d0ff02 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -124,6 +124,16 @@ test_expect_success 'setup' ' EOF ' +test_expect_success '--list notices extra parameters' ' + test_must_fail git archive --list blah && + test_must_fail git archive --remote=. --list blah +' + +test_expect_success 'end-of-options is correctly eaten' ' + git archive --list --end-of-options && + git archive --remote=. --list --end-of-options +' + test_expect_success 'populate workdir' ' mkdir a && echo simple textfile >a/a && diff --git a/t/t5003-archive-zip.sh b/t/t5003-archive-zip.sh index fc499cdff0..961c6aac25 100755 --- a/t/t5003-archive-zip.sh +++ b/t/t5003-archive-zip.sh @@ -239,4 +239,38 @@ check_zip with_untracked2 check_added with_untracked2 untracked one/untracked check_added with_untracked2 untracked two/untracked +# Test remote archive over HTTP protocol. +# +# Note: this should be the last part of this test suite, because +# by including lib-httpd.sh, the test may end early if httpd tests +# should not be run. +# +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +test_expect_success "setup for HTTP protocol" ' + cp -R bare.git "$HTTPD_DOCUMENT_ROOT_PATH/bare.git" && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/bare.git" \ + config http.uploadpack true && + set_askpass user@host pass@host +' + +setup_askpass_helper + +test_expect_success 'remote archive does not work with protocol v1' ' + test_must_fail git -c protocol.version=1 archive \ + --remote="$HTTPD_URL/auth/smart/bare.git" \ + --output=remote-http.zip HEAD >actual 2>&1 && + cat >expect <<-EOF && + fatal: can${SQ}t connect to subservice git-upload-archive + EOF + test_cmp expect actual +' + +test_expect_success 'archive remote http repository' ' + git archive --remote="$HTTPD_URL/auth/smart/bare.git" \ + --output=remote-http.zip HEAD && + test_cmp_bin d.zip remote-http.zip +' + test_done diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh index db11cababd..654d8cf3ee 100755 --- a/t/t5100-mailinfo.sh +++ b/t/t5100-mailinfo.sh @@ -268,4 +268,26 @@ test_expect_success 'mailinfo warn CR in base64 encoded email' ' test_must_be_empty quoted-cr/0002.err ' +test_expect_success 'from line with unterminated quoted string' ' + echo "From: bob \"unterminated string smith <bob@example.com>" >in && + git mailinfo /dev/null /dev/null <in >actual && + cat >expect <<-\EOF && + Author: bob unterminated string smith + Email: bob@example.com + + EOF + test_cmp expect actual +' + +test_expect_success 'from line with unterminated comment' ' + echo "From: bob (unterminated comment smith <bob@example.com>" >in && + git mailinfo /dev/null /dev/null <in >actual && + cat >expect <<-\EOF && + Author: bob (unterminated comment smith + Email: bob@example.com + + EOF + test_cmp expect actual +' + test_done diff --git a/t/t5100/comment.expect b/t/t5100/comment.expect index 7228177984..bd71956a47 100644 --- a/t/t5100/comment.expect +++ b/t/t5100/comment.expect @@ -1,4 +1,4 @@ -Author: A U Thor (this is (really) a comment (honestly)) +Author: (this is (really) a "comment" (honestly)) A U Thor Email: somebody@example.com Subject: testing comments Date: Sun, 25 May 2008 00:38:18 -0700 diff --git a/t/t5100/comment.in b/t/t5100/comment.in index c53a192dfe..0b7e903b06 100644 --- a/t/t5100/comment.in +++ b/t/t5100/comment.in @@ -1,5 +1,5 @@ From 1234567890123456789012345678901234567890 Mon Sep 17 00:00:00 2001 -From: "A U Thor" <somebody@example.com> (this is \(really\) a comment (honestly)) +From: (this is \(really\) a "comment" (honestly)) "A U Thor" <somebody@example.com> Date: Sun, 25 May 2008 00:38:18 -0700 Subject: [PATCH] testing comments diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index d402ec18b7..a58f91035d 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -441,6 +441,47 @@ test_expect_success 'index-pack with --strict' ' ) ' +test_expect_success 'setup for --strict and --fsck-objects downgrading fsck msgs' ' + git init strict && + ( + cd strict && + test_commit first hello && + cat >commit <<-EOF && + tree $(git rev-parse HEAD^{tree}) + parent $(git rev-parse HEAD) + author A U Thor + committer A U Thor + + commit: this is a commit with bad emails + + EOF + git hash-object --literally -t commit -w --stdin <commit >commit_list && + git pack-objects test <commit_list >pack-name + ) +' + +test_with_bad_commit () { + must_fail_arg="$1" && + must_pass_arg="$2" && + ( + cd strict && + test_expect_fail git index-pack "$must_fail_arg" "test-$(cat pack-name).pack" + git index-pack "$must_pass_arg" "test-$(cat pack-name).pack" + ) +} + +test_expect_success 'index-pack with --strict downgrading fsck msgs' ' + test_with_bad_commit --strict --strict="missingEmail=ignore" +' + +test_expect_success 'index-pack with --fsck-objects downgrading fsck msgs' ' + test_with_bad_commit --fsck-objects --fsck-objects="missingEmail=ignore" +' + +test_expect_success 'cleanup for --strict and --fsck-objects downgrading fsck msgs' ' + rm -rf strict +' + test_expect_success 'honor pack.packSizeLimit' ' git config pack.packSizeLimit 3m && packname_10=$(git pack-objects test-10 <obj-list) && diff --git a/t/t5312-prune-corruption.sh b/t/t5312-prune-corruption.sh index 230cb38712..d8d2e30468 100755 --- a/t/t5312-prune-corruption.sh +++ b/t/t5312-prune-corruption.sh @@ -111,30 +111,4 @@ test_expect_success 'pack-refs does not silently delete broken loose ref' ' test_cmp expect actual ' -# we do not want to count on running pack-refs to -# actually pack it, as it is perfectly reasonable to -# skip processing a broken ref -test_expect_success REFFILES 'create packed-refs file with broken ref' ' - rm -f .git/refs/heads/main && - cat >.git/packed-refs <<-EOF && - $missing refs/heads/main - $recoverable refs/heads/other - EOF - echo $missing >expect && - git rev-parse refs/heads/main >actual && - test_cmp expect actual -' - -test_expect_success REFFILES 'pack-refs does not silently delete broken packed ref' ' - git pack-refs --all --prune && - git rev-parse refs/heads/main >actual && - test_cmp expect actual -' - -test_expect_success REFFILES 'pack-refs does not drop broken refs during deletion' ' - git update-ref -d refs/heads/other && - git rev-parse refs/heads/main >actual && - test_cmp expect actual -' - test_done diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index d4fc65e078..a2b4442660 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -540,17 +540,17 @@ test_expect_success 'detect low chunk count' ' test_expect_success 'detect missing OID fanout chunk' ' corrupt_graph_and_verify $GRAPH_BYTE_OID_FANOUT_ID "\0" \ - "missing the OID Fanout chunk" + "commit-graph required OID fanout chunk missing or corrupted" ' test_expect_success 'detect missing OID lookup chunk' ' corrupt_graph_and_verify $GRAPH_BYTE_OID_LOOKUP_ID "\0" \ - "missing the OID Lookup chunk" + "commit-graph required OID lookup chunk missing or corrupted" ' test_expect_success 'detect missing commit data chunk' ' corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_DATA_ID "\0" \ - "missing the Commit Data chunk" + "commit-graph required commit data chunk missing or corrupted" ' test_expect_success 'detect incorrect fanout' ' @@ -560,7 +560,7 @@ test_expect_success 'detect incorrect fanout' ' test_expect_success 'detect incorrect fanout final value' ' corrupt_graph_and_verify $GRAPH_BYTE_FANOUT2 "\01" \ - "oid table and fanout disagree on size" + "OID lookup chunk is the wrong size" ' test_expect_success 'detect incorrect OID order' ' @@ -842,7 +842,7 @@ test_expect_success 'reader notices too-small oid fanout chunk' ' check_corrupt_chunk OIDF clear $(printf "000000%02x" $(test_seq 250)) && cat >expect.err <<-\EOF && error: commit-graph oid fanout chunk is wrong size - error: commit-graph is missing the OID Fanout chunk + error: commit-graph required OID fanout chunk missing or corrupted EOF test_cmp expect.err err ' @@ -850,7 +850,8 @@ test_expect_success 'reader notices too-small oid fanout chunk' ' test_expect_success 'reader notices fanout/lookup table mismatch' ' check_corrupt_chunk OIDF 1020 "FFFFFFFF" && cat >expect.err <<-\EOF && - error: commit-graph oid table and fanout disagree on size + error: commit-graph OID lookup chunk is the wrong size + error: commit-graph required OID lookup chunk missing or corrupted EOF test_cmp expect.err err ' @@ -866,6 +867,7 @@ test_expect_success 'reader notices out-of-bounds fanout' ' check_corrupt_chunk OIDF 0 $(printf "%02x000000" $(test_seq 0 254)) && cat >expect.err <<-\EOF && error: commit-graph fanout values out of order + error: commit-graph required OID fanout chunk missing or corrupted EOF test_cmp expect.err err ' @@ -874,7 +876,7 @@ test_expect_success 'reader notices too-small commit data chunk' ' check_corrupt_chunk CDAT clear 00000000 && cat >expect.err <<-\EOF && error: commit-graph commit data chunk is wrong size - error: commit-graph is missing the Commit Data chunk + error: commit-graph required commit data chunk missing or corrupted EOF test_cmp expect.err err ' @@ -909,10 +911,10 @@ test_expect_success 'stale commit cannot be parsed when given directly' ' # Verify that it is possible to read the commit from the # commit graph when not being paranoid, ... - GIT_COMMIT_GRAPH_PARANOIA=false git rev-list B && + git rev-list B && # ... but parsing the commit when double checking that # it actually exists in the object database should fail. - test_must_fail git rev-list -1 B + test_must_fail env GIT_COMMIT_GRAPH_PARANOIA=true git rev-list -1 B ) ' @@ -936,9 +938,9 @@ test_expect_success 'stale commit cannot be parsed when traversing graph' ' # Again, we should be able to parse the commit when not # being paranoid about commit graph staleness... - GIT_COMMIT_GRAPH_PARANOIA=false git rev-parse HEAD~2 && + git rev-parse HEAD~2 && # ... but fail when we are paranoid. - test_must_fail git rev-parse HEAD~2 2>error && + test_must_fail env GIT_COMMIT_GRAPH_PARANOIA=true git rev-parse HEAD~2 2>error && grep "error: commit $oid exists in commit-graph but not in the object database" error ) ' diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index c4c6060cee..dd09134db0 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -1157,4 +1157,53 @@ test_expect_success 'reader notices too-small revindex chunk' ' test_cmp expect.err err ' +test_expect_success 'reader notices out-of-bounds fanout' ' + # This is similar to the out-of-bounds fanout test in t5318. The values + # in adjacent entries should be large but not identical (they + # are used as hi/lo starts for a binary search, which would then abort + # immediately). + corrupt_chunk OIDF 0 $(printf "%02x000000" $(test_seq 0 254)) && + test_must_fail git log 2>err && + cat >expect <<-\EOF && + error: oid fanout out of order: fanout[254] = fe000000 > 5c = fanout[255] + fatal: multi-pack-index required OID fanout chunk missing or corrupted + EOF + test_cmp expect err +' + +test_expect_success 'bitmapped packs are stored via the BTMP chunk' ' + test_when_finished "rm -fr repo" && + git init repo && + ( + cd repo && + + for i in 1 2 3 4 5 + do + test_commit "$i" && + git repack -d || return 1 + done && + + find $objdir/pack -type f -name "*.idx" | xargs -n 1 basename | + sort >packs && + + git multi-pack-index write --stdin-packs <packs && + test_must_fail test-tool read-midx --bitmap $objdir 2>err && + cat >expect <<-\EOF && + error: MIDX does not contain the BTMP chunk + EOF + test_cmp expect err && + + git multi-pack-index write --stdin-packs --bitmap \ + --preferred-pack="$(head -n1 <packs)" <packs && + test-tool read-midx --bitmap $objdir >actual && + for i in $(test_seq $(wc -l <packs)) + do + sed -ne "${i}s/\.idx$/\.pack/p" packs && + echo " bitmap_pos: $((($i - 1) * 3))" && + echo " bitmap_nr: 3" || return 1 + done >expect && + test_cmp expect actual + ) +' + test_done diff --git a/t/t5332-multi-pack-reuse.sh b/t/t5332-multi-pack-reuse.sh new file mode 100755 index 0000000000..3c20738bce --- /dev/null +++ b/t/t5332-multi-pack-reuse.sh @@ -0,0 +1,207 @@ +#!/bin/sh + +test_description='pack-objects multi-pack reuse' + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-bitmap.sh + +objdir=.git/objects +packdir=$objdir/pack + +test_pack_reused () { + test_trace2_data pack-objects pack-reused "$1" +} + +test_packs_reused () { + test_trace2_data pack-objects packs-reused "$1" +} + + +# pack_position <object> </path/to/pack.idx +pack_position () { + git show-index >objects && + grep "$1" objects | cut -d" " -f1 +} + +# test_pack_objects_reused_all <pack-reused> <packs-reused> +test_pack_objects_reused_all () { + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --revs --all --delta-base-offset \ + >/dev/null && + + test_pack_reused "$1" <trace2.txt && + test_packs_reused "$2" <trace2.txt +} + +# test_pack_objects_reused <pack-reused> <packs-reused> +test_pack_objects_reused () { + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --revs >/dev/null && + + test_pack_reused "$1" <trace2.txt && + test_packs_reused "$2" <trace2.txt +} + +test_expect_success 'preferred pack is reused for single-pack reuse' ' + test_config pack.allowPackReuse single && + + for i in A B + do + test_commit "$i" && + git repack -d || return 1 + done && + + git multi-pack-index write --bitmap && + + test_pack_objects_reused_all 3 1 +' + +test_expect_success 'multi-pack reuse is disabled by default' ' + test_pack_objects_reused_all 3 1 +' + +test_expect_success 'feature.experimental implies multi-pack reuse' ' + test_config feature.experimental true && + + test_pack_objects_reused_all 6 2 +' + +test_expect_success 'multi-pack reuse can be disabled with feature.experimental' ' + test_config feature.experimental true && + test_config pack.allowPackReuse single && + + test_pack_objects_reused_all 3 1 +' + +test_expect_success 'enable multi-pack reuse' ' + git config pack.allowPackReuse multi +' + +test_expect_success 'reuse all objects from subset of bitmapped packs' ' + test_commit C && + git repack -d && + + git multi-pack-index write --bitmap && + + cat >in <<-EOF && + $(git rev-parse C) + ^$(git rev-parse A) + EOF + + test_pack_objects_reused 6 2 <in +' + +test_expect_success 'reuse all objects from all packs' ' + test_pack_objects_reused_all 9 3 +' + +test_expect_success 'reuse objects from first pack with middle gap' ' + for i in D E F + do + test_commit "$i" || return 1 + done && + + # Set "pack.window" to zero to ensure that we do not create any + # deltas, which could alter the amount of pack reuse we perform + # (if, for e.g., we are not sending one or more bases). + D="$(git -c pack.window=0 pack-objects --all --unpacked $packdir/pack)" && + + d_pos="$(pack_position $(git rev-parse D) <$packdir/pack-$D.idx)" && + e_pos="$(pack_position $(git rev-parse E) <$packdir/pack-$D.idx)" && + f_pos="$(pack_position $(git rev-parse F) <$packdir/pack-$D.idx)" && + + # commits F, E, and D, should appear in that order at the + # beginning of the pack + test $f_pos -lt $e_pos && + test $e_pos -lt $d_pos && + + # Ensure that the pack we are constructing sorts ahead of any + # other packs in lexical/bitmap order by choosing it as the + # preferred pack. + git multi-pack-index write --bitmap --preferred-pack="pack-$D.idx" && + + cat >in <<-EOF && + $(git rev-parse E) + ^$(git rev-parse D) + EOF + + test_pack_objects_reused 3 1 <in +' + +test_expect_success 'reuse objects from middle pack with middle gap' ' + rm -fr $packdir/multi-pack-index* && + + # Ensure that the pack we are constructing sort into any + # position *but* the first one, by choosing a different pack as + # the preferred one. + git multi-pack-index write --bitmap --preferred-pack="pack-$A.idx" && + + cat >in <<-EOF && + $(git rev-parse E) + ^$(git rev-parse D) + EOF + + test_pack_objects_reused 3 1 <in +' + +test_expect_success 'omit delta with uninteresting base (same pack)' ' + git repack -adk && + + test_seq 32 >f && + git add f && + test_tick && + git commit -m "delta" && + delta="$(git rev-parse HEAD)" && + + test_seq 64 >f && + test_tick && + git commit -a -m "base" && + base="$(git rev-parse HEAD)" && + + test_commit other && + + git repack -d && + + have_delta "$(git rev-parse $delta:f)" "$(git rev-parse $base:f)" && + + git multi-pack-index write --bitmap && + + cat >in <<-EOF && + $(git rev-parse other) + ^$base + EOF + + # We can only reuse the 3 objects corresponding to "other" from + # the latest pack. + # + # This is because even though we want "delta", we do not want + # "base", meaning that we have to inflate the delta/base-pair + # corresponding to the blob in commit "delta", which bypasses + # the pack-reuse mechanism. + # + # The remaining objects from the other pack are similarly not + # reused because their objects are on the uninteresting side of + # the query. + test_pack_objects_reused 3 1 <in +' + +test_expect_success 'omit delta from uninteresting base (cross pack)' ' + cat >in <<-EOF && + $(git rev-parse $base) + ^$(git rev-parse $delta) + EOF + + P="$(git pack-objects --revs $packdir/pack <in)" && + + git multi-pack-index write --bitmap --preferred-pack="pack-$P.idx" && + + packs_nr="$(find $packdir -type f -name "pack-*.pack" | wc -l)" && + objects_nr="$(git rev-list --count --all --objects)" && + + test_pack_objects_reused_all $(($objects_nr - 1)) $packs_nr +' + +test_done diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh index 001b7a17ad..8b8bc47dc0 100755 --- a/t/t5401-update-hooks.sh +++ b/t/t5401-update-hooks.sh @@ -133,10 +133,8 @@ test_expect_success 'pre-receive hook that forgets to read its input' ' EOF rm -f victim.git/hooks/update victim.git/hooks/post-update && - for v in $(test_seq 100 999) - do - git branch branch_$v main || return - done && + printf "create refs/heads/branch_%d main\n" $(test_seq 100 999) >input && + git update-ref --stdin <input && git push ./victim.git "+refs/heads/*:refs/heads/*" ' diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index dcadd56d3a..33d34d5ae9 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -169,6 +169,7 @@ test_expect_success REFFILES 'fetch --prune fails to delete branches' ' git clone . prune-fail && cd prune-fail && git update-ref refs/remotes/origin/extrabranch main && + git pack-refs --all && : this will prevent --prune from locking packed-refs for deleting refs, but adding loose refs still succeeds && >.git/packed-refs.new && @@ -802,7 +803,8 @@ test_expect_success 'fetch.writeCommitGraph with submodules' ' cd super-clone && rm -rf .git/objects/info && git -c fetch.writeCommitGraph=true fetch origin && - test_path_is_file .git/objects/info/commit-graphs/commit-graph-chain + test_path_is_file .git/objects/info/commit-graphs/commit-graph-chain && + git -c fetch.writeCommitGraph=true fetch --recurse-submodules origin ) ' diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh index a95841dc36..25772c85c5 100755 --- a/t/t5514-fetch-multiple.sh +++ b/t/t5514-fetch-multiple.sh @@ -24,6 +24,15 @@ setup_repository () { ) } +setup_test_clone () { + test_dir="$1" && + git clone one "$test_dir" && + for r in one two three + do + git -C "$test_dir" remote add "$r" "../$r" || return 1 + done +} + test_expect_success setup ' setup_repository one && setup_repository two && @@ -209,4 +218,156 @@ test_expect_success 'git fetch --multiple --jobs=0 picks a default' ' git fetch --multiple --jobs=0) ' +create_fetch_all_expect () { + cat >expect <<-\EOF + one/main + one/side + origin/HEAD -> origin/main + origin/main + origin/side + three/another + three/main + three/side + two/another + two/main + two/side + EOF +} + +for fetch_all in true false +do + test_expect_success "git fetch --all (works with fetch.all = $fetch_all)" ' + test_dir="test_fetch_all_$fetch_all" && + setup_test_clone "$test_dir" && + ( + cd "$test_dir" && + git config fetch.all $fetch_all && + git fetch --all && + create_fetch_all_expect && + git branch -r >actual && + test_cmp expect actual + ) + ' +done + +test_expect_success 'git fetch (fetch all remotes with fetch.all = true)' ' + setup_test_clone test9 && + ( + cd test9 && + git config fetch.all true && + git fetch && + git branch -r >actual && + create_fetch_all_expect && + test_cmp expect actual + ) +' + +create_fetch_one_expect () { + cat >expect <<-\EOF + one/main + one/side + origin/HEAD -> origin/main + origin/main + origin/side + EOF +} + +test_expect_success 'git fetch one (explicit remote overrides fetch.all)' ' + setup_test_clone test10 && + ( + cd test10 && + git config fetch.all true && + git fetch one && + create_fetch_one_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +create_fetch_two_as_origin_expect () { + cat >expect <<-\EOF + origin/HEAD -> origin/main + origin/another + origin/main + origin/side + EOF +} + +test_expect_success 'git config fetch.all false (fetch only default remote)' ' + setup_test_clone test11 && + ( + cd test11 && + git config fetch.all false && + git remote set-url origin ../two && + git fetch && + create_fetch_two_as_origin_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +for fetch_all in true false +do + test_expect_success "git fetch --no-all (fetch only default remote with fetch.all = $fetch_all)" ' + test_dir="test_no_all_fetch_all_$fetch_all" && + setup_test_clone "$test_dir" && + ( + cd "$test_dir" && + git config fetch.all $fetch_all && + git remote set-url origin ../two && + git fetch --no-all && + create_fetch_two_as_origin_expect && + git branch -r >actual && + test_cmp expect actual + ) + ' +done + +test_expect_success 'git fetch --no-all (fetch only default remote without fetch.all)' ' + setup_test_clone test12 && + ( + cd test12 && + git config --unset-all fetch.all || true && + git remote set-url origin ../two && + git fetch --no-all && + create_fetch_two_as_origin_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +test_expect_success 'git fetch --all --no-all (fetch only default remote)' ' + setup_test_clone test13 && + ( + cd test13 && + git remote set-url origin ../two && + git fetch --all --no-all && + create_fetch_two_as_origin_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +test_expect_success 'git fetch --no-all one (fetch only explicit remote)' ' + setup_test_clone test14 && + ( + cd test14 && + git fetch --no-all one && + create_fetch_one_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +test_expect_success 'git fetch --no-all --all (fetch all remotes)' ' + setup_test_clone test15 && + ( + cd test15 && + git fetch --no-all --all && + create_fetch_all_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh index 26e933f93a..5e566205ba 100755 --- a/t/t5526-fetch-submodules.sh +++ b/t/t5526-fetch-submodules.sh @@ -771,7 +771,7 @@ test_expect_success 'fetching submodule into a broken repository' ' git -C dst fetch --recurse-submodules && # Break the receiving submodule - rm -f dst/sub/.git/HEAD && + rm -r dst/sub/.git/objects && # NOTE: without the fix the following tests will recurse forever! # They should terminate with an error. diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index df758e187d..71428f3d5c 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -232,8 +232,9 @@ test_expect_success 'push --atomic fails on server-side errors' ' test_config -C "$d" http.receivepack true && up="$HTTPD_URL"/smart/atomic-branches.git && - # break ref updates for other on the remote site - mkdir "$d/refs/heads/other.lock" && + # Create d/f conflict to break ref updates for other on the remote site. + git -C "$d" update-ref -d refs/heads/other && + git -C "$d" update-ref refs/heads/other/conflict HEAD && # add the new commit to other git branch -f other collateral && @@ -241,18 +242,9 @@ test_expect_success 'push --atomic fails on server-side errors' ' # --atomic should cause entire push to be rejected test_must_fail git push --atomic "$up" atomic other 2>output && - # the new branch should not have been created upstream - test_must_fail git -C "$d" show-ref --verify refs/heads/atomic && - - # upstream should still reflect atomic2, the last thing we pushed - # successfully - git rev-parse atomic2 >expected && - # ...to other. - git -C "$d" rev-parse refs/heads/other >actual && - test_cmp expected actual && - - # the new branch should not have been created upstream + # The atomic and other branches should not be created upstream. test_must_fail git -C "$d" show-ref --verify refs/heads/atomic && + test_must_fail git -C "$d" show-ref --verify refs/heads/other && # the failed refs should be indicated to the user grep "^ ! .*rejected.* other -> other .*atomic transaction failed" output && diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index e444b30bf6..4c3b32785d 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -66,11 +66,11 @@ test_expect_success 'create empty remote repository' ' setup_post_update_server_info_hook "$HTTPD_DOCUMENT_ROOT_PATH/empty.git" ' -test_expect_success 'empty dumb HTTP repository has default hash algorithm' ' +test_expect_success 'empty dumb HTTP repository falls back to SHA1' ' test_when_finished "rm -fr clone-empty" && git clone $HTTPD_URL/dumb/empty.git clone-empty && git -C clone-empty rev-parse --show-object-format >empty-format && - test "$(cat empty-format)" = "$(test_oid algo)" + test "$(cat empty-format)" = sha1 ' setup_askpass_helper diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index 8a41adf1e1..a623a1058c 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -359,7 +359,9 @@ create_tags () { # now assign tags to all the dangling commits we created above tag=$(perl -e "print \"bla\" x 30") && - sed -e "s|^:\([^ ]*\) \(.*\)$|\2 refs/tags/$tag-\1|" <marks >>packed-refs + sed -e "s|^:\([^ ]*\) \(.*\)$|create refs/tags/$tag-\1 \2|" <marks >input && + git update-ref --stdin <input && + rm input } test_expect_success 'create 2,000 tags in the repo' ' @@ -731,4 +733,22 @@ test_expect_success 'no empty path components' ' ! grep "//" log ' +test_expect_success 'tag following always works over v0 http' ' + upstream=$HTTPD_DOCUMENT_ROOT_PATH/tags && + git init "$upstream" && + ( + cd "$upstream" && + git commit --allow-empty -m base && + git tag not-annotated && + git tag -m foo annotated + ) && + git init tags && + git -C tags -c protocol.version=0 \ + fetch --depth 1 $HTTPD_URL/smart/tags \ + refs/tags/annotated:refs/tags/annotated && + git -C "$upstream" for-each-ref refs/tags >expect && + git -C tags for-each-ref >actual && + test_cmp expect actual +' + test_done diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh index 996a08e90c..1ca5f745e7 100755 --- a/t/t5558-clone-bundle-uri.sh +++ b/t/t5558-clone-bundle-uri.sh @@ -33,6 +33,15 @@ test_expect_success 'clone with path bundle' ' test_cmp expect actual ' +test_expect_success 'clone with path bundle and non-default hash' ' + test_when_finished "rm -rf clone-path-non-default-hash" && + GIT_DEFAULT_HASH=sha256 git clone --bundle-uri="clone-from/B.bundle" \ + clone-from clone-path-non-default-hash && + git -C clone-path-non-default-hash rev-parse refs/bundles/topic >actual && + git -C clone-from rev-parse topic >expect && + test_cmp expect actual +' + test_expect_success 'clone with file:// bundle' ' git clone --bundle-uri="file://$(pwd)/clone-from/B.bundle" \ clone-from clone-file && @@ -284,6 +293,15 @@ test_expect_success 'clone HTTP bundle' ' test_config -C clone-http log.excludedecoration refs/bundle/ ' +test_expect_success 'clone HTTP bundle with non-default hash' ' + test_when_finished "rm -rf clone-http-non-default-hash" && + GIT_DEFAULT_HASH=sha256 git clone --bundle-uri="$HTTPD_URL/B.bundle" \ + "$HTTPD_URL/smart/fetch.git" clone-http-non-default-hash && + git -C clone-http-non-default-hash rev-parse refs/bundles/topic >actual && + git -C clone-from rev-parse topic >expect && + test_cmp expect actual +' + test_expect_success 'clone bundle list (HTTP, no heuristic)' ' test_when_finished rm -f trace*.txt && diff --git a/t/t5562/invoke-with-content-length.pl b/t/t5562/invoke-with-content-length.pl index 718dd9b49d..9babb9a375 100644 --- a/t/t5562/invoke-with-content-length.pl +++ b/t/t5562/invoke-with-content-length.pl @@ -1,4 +1,4 @@ -use 5.008; +use 5.008001; use strict; use warnings; diff --git a/t/t5574-fetch-output.sh b/t/t5574-fetch-output.sh index a9b06b2251..5883839a04 100755 --- a/t/t5574-fetch-output.sh +++ b/t/t5574-fetch-output.sh @@ -61,11 +61,10 @@ test_expect_success 'fetch compact output' ' test_cmp expect actual ' -test_expect_success 'fetch porcelain output' ' - test_when_finished "rm -rf porcelain" && - +test_expect_success 'setup for fetch porcelain output' ' # Set up a bunch of references that we can use to demonstrate different # kinds of flag symbols in the output format. + test_commit commit-for-porcelain-output && MAIN_OLD=$(git rev-parse HEAD) && git branch "fast-forward" && git branch "deleted-branch" && @@ -74,15 +73,10 @@ test_expect_success 'fetch porcelain output' ' FORCE_UPDATED_OLD=$(git rev-parse HEAD) && git checkout main && - # Clone and pre-seed the repositories. We fetch references into two - # namespaces so that we can test that rejected and force-updated - # references are reported properly. - refspecs="refs/heads/*:refs/unforced/* +refs/heads/*:refs/forced/*" && - git clone . porcelain && - git -C porcelain fetch origin $refspecs && + # Backup to preseed.git + git clone --mirror . preseed.git && - # Now that we have set up the client repositories we can change our - # local references. + # Continue changing our local references. git branch new-branch && git branch -d deleted-branch && git checkout fast-forward && @@ -91,36 +85,53 @@ test_expect_success 'fetch porcelain output' ' git checkout force-updated && git reset --hard HEAD~ && test_commit --no-tag force-update-new && - FORCE_UPDATED_NEW=$(git rev-parse HEAD) && - - cat >expect <<-EOF && - - $MAIN_OLD $ZERO_OID refs/forced/deleted-branch - - $MAIN_OLD $ZERO_OID refs/unforced/deleted-branch - $MAIN_OLD $FAST_FORWARD_NEW refs/unforced/fast-forward - ! $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/unforced/force-updated - * $ZERO_OID $MAIN_OLD refs/unforced/new-branch - $MAIN_OLD $FAST_FORWARD_NEW refs/forced/fast-forward - + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/forced/force-updated - * $ZERO_OID $MAIN_OLD refs/forced/new-branch - $MAIN_OLD $FAST_FORWARD_NEW refs/remotes/origin/fast-forward - + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/remotes/origin/force-updated - * $ZERO_OID $MAIN_OLD refs/remotes/origin/new-branch - EOF - - # Execute a dry-run fetch first. We do this to assert that the dry-run - # and non-dry-run fetches produces the same output. Execution of the - # fetch is expected to fail as we have a rejected reference update. - test_must_fail git -C porcelain fetch \ - --porcelain --dry-run --prune origin $refspecs >actual && - test_cmp expect actual && - - # And now we perform a non-dry-run fetch. - test_must_fail git -C porcelain fetch \ - --porcelain --prune origin $refspecs >actual 2>stderr && - test_cmp expect actual && - test_must_be_empty stderr + FORCE_UPDATED_NEW=$(git rev-parse HEAD) ' +for opt in "" "--atomic" +do + test_expect_success "fetch porcelain output ${opt:+(atomic)}" ' + test_when_finished "rm -rf porcelain" && + + # Clone and pre-seed the repositories. We fetch references into two + # namespaces so that we can test that rejected and force-updated + # references are reported properly. + refspecs="refs/heads/*:refs/unforced/* +refs/heads/*:refs/forced/*" && + git clone preseed.git porcelain && + git -C porcelain fetch origin $opt $refspecs && + + cat >expect <<-EOF && + - $MAIN_OLD $ZERO_OID refs/forced/deleted-branch + - $MAIN_OLD $ZERO_OID refs/unforced/deleted-branch + $MAIN_OLD $FAST_FORWARD_NEW refs/unforced/fast-forward + ! $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/unforced/force-updated + * $ZERO_OID $MAIN_OLD refs/unforced/new-branch + $MAIN_OLD $FAST_FORWARD_NEW refs/forced/fast-forward + + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/forced/force-updated + * $ZERO_OID $MAIN_OLD refs/forced/new-branch + $MAIN_OLD $FAST_FORWARD_NEW refs/remotes/origin/fast-forward + + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/remotes/origin/force-updated + * $ZERO_OID $MAIN_OLD refs/remotes/origin/new-branch + EOF + + # Change the URL of the repository to fetch different references. + git -C porcelain remote set-url origin .. && + + # Execute a dry-run fetch first. We do this to assert that the dry-run + # and non-dry-run fetches produces the same output. Execution of the + # fetch is expected to fail as we have a rejected reference update. + test_must_fail git -C porcelain fetch $opt \ + --porcelain --dry-run --prune origin $refspecs >actual && + test_cmp expect actual && + + # And now we perform a non-dry-run fetch. + test_must_fail git -C porcelain fetch $opt \ + --porcelain --prune origin $refspecs >actual 2>stderr && + test_cmp expect actual && + test_must_be_empty stderr + ' +done + test_expect_success 'fetch porcelain with multiple remotes' ' test_when_finished "rm -rf porcelain" && diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 47eae641f0..fb1b9c686d 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -157,6 +157,23 @@ test_expect_success 'clone --mirror does not repeat tags' ' ' +test_expect_success 'clone with files ref format' ' + test_when_finished "rm -rf ref-storage" && + git clone --ref-format=files --mirror src ref-storage && + echo files >expect && + git -C ref-storage rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'clone with garbage ref format' ' + cat >expect <<-EOF && + fatal: unknown ref storage format ${SQ}garbage${SQ} + EOF + test_must_fail git clone --ref-format=garbage --mirror src ref-storage 2>err && + test_cmp expect err && + test_path_is_missing ref-storage +' + test_expect_success 'clone to destination with trailing /' ' git clone src target-1/ && diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh index 946c575188..a3055869bc 100755 --- a/t/t5605-clone-local.sh +++ b/t/t5605-clone-local.sh @@ -65,7 +65,7 @@ test_expect_success 'Even without -l, local will make a hardlink' ' ' test_expect_success 'local clone of repo with nonexistent ref in HEAD' ' - echo "ref: refs/heads/nonexistent" > a.git/HEAD && + git -C a.git symbolic-ref HEAD refs/heads/nonexistent && git clone a d && (cd d && git fetch && @@ -157,7 +157,7 @@ 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' ' +test_expect_success REFFILES 'local clone from repo with corrupt refs fails gracefully' ' git init corrupt && test_commit -C corrupt one && echo a >corrupt/.git/refs/heads/topic && diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh index fc4bbd9daf..a400bcca62 100755 --- a/t/t5606-clone-options.sh +++ b/t/t5606-clone-options.sh @@ -64,7 +64,7 @@ test_expect_success 'disallows --bundle-uri with shallow options' ' for option in --depth=1 --shallow-since=01-01-2000 --shallow-exclude=HEAD do test_must_fail git clone --bundle-uri=bundle $option from to 2>err && - grep "bundle-uri is incompatible" err || return 1 + grep "bundle-uri.* cannot be used together" err || return 1 done ' diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 3c0c6047d5..6ef4971845 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -221,7 +221,9 @@ test_expect_success 'clone of empty repo propagates name of default branch' ' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ git -c init.defaultBranch=main -c protocol.version=2 \ clone "file://$(pwd)/file_empty_parent" file_empty_child && - grep "refs/heads/mydefaultbranch" file_empty_child/.git/HEAD + echo refs/heads/mydefaultbranch >expect && + git -C file_empty_child symbolic-ref HEAD >actual && + test_cmp expect actual ' test_expect_success '...but not if explicitly forbidden by config' ' @@ -234,7 +236,9 @@ test_expect_success '...but not if explicitly forbidden by config' ' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \ git -c init.defaultBranch=main -c protocol.version=2 \ clone "file://$(pwd)/file_empty_parent" file_empty_child && - ! grep "refs/heads/mydefaultbranch" file_empty_child/.git/HEAD + echo refs/heads/main >expect && + git -C file_empty_child symbolic-ref HEAD >actual && + test_cmp expect actual ' test_expect_success 'bare clone propagates empty default branch' ' @@ -247,7 +251,9 @@ test_expect_success 'bare clone propagates empty default branch' ' git -c init.defaultBranch=main -c protocol.version=2 \ clone --bare \ "file://$(pwd)/file_empty_parent" file_empty_child.git && - grep "refs/heads/mydefaultbranch" file_empty_child.git/HEAD + echo "refs/heads/mydefaultbranch" >expect && + git -C file_empty_child.git symbolic-ref HEAD >actual && + test_cmp expect actual ' test_expect_success 'clone propagates unborn HEAD from non-empty repo' ' @@ -265,7 +271,9 @@ test_expect_success 'clone propagates unborn HEAD from non-empty repo' ' git -c init.defaultBranch=main -c protocol.version=2 \ clone "file://$(pwd)/file_unborn_parent" \ file_unborn_child 2>stderr && - grep "refs/heads/mydefaultbranch" file_unborn_child/.git/HEAD && + echo "refs/heads/mydefaultbranch" >expect && + git -C file_unborn_child symbolic-ref HEAD >actual && + test_cmp expect actual && grep "warning: remote HEAD refers to nonexistent ref" stderr ' @@ -295,7 +303,9 @@ test_expect_success 'bare clone propagates unborn HEAD from non-empty repo' ' git -c init.defaultBranch=main -c protocol.version=2 \ clone --bare "file://$(pwd)/file_unborn_parent" \ file_unborn_child.git 2>stderr && - grep "refs/heads/mydefaultbranch" file_unborn_child.git/HEAD && + echo "refs/heads/mydefaultbranch" >expect && + git -C file_unborn_child.git symbolic-ref HEAD >actual && + test_cmp expect actual && ! grep "warning:" stderr ' @@ -315,7 +325,9 @@ test_expect_success 'defaulted HEAD uses remote branch if available' ' git -c init.defaultBranch=branchwithstuff -c protocol.version=2 \ clone "file://$(pwd)/file_unborn_parent" \ file_unborn_child 2>stderr && - grep "refs/heads/branchwithstuff" file_unborn_child/.git/HEAD && + echo "refs/heads/branchwithstuff" >expect && + git -C file_unborn_child symbolic-ref HEAD >actual && + test_cmp expect actual && test_path_is_file file_unborn_child/stuff.t && ! grep "warning:" stderr ' diff --git a/t/t6005-rev-list-count.sh b/t/t6005-rev-list-count.sh index 0729f800c3..ee0306aeec 100755 --- a/t/t6005-rev-list-count.sh +++ b/t/t6005-rev-list-count.sh @@ -18,20 +18,34 @@ test_expect_success 'no options' ' ' test_expect_success '--max-count' ' + test_must_fail git rev-list --max-count=1q HEAD 2>error && + grep "not an integer" error && + test_stdout_line_count = 0 git rev-list HEAD --max-count=0 && test_stdout_line_count = 3 git rev-list HEAD --max-count=3 && test_stdout_line_count = 5 git rev-list HEAD --max-count=5 && - test_stdout_line_count = 5 git rev-list HEAD --max-count=10 + test_stdout_line_count = 5 git rev-list HEAD --max-count=10 && + test_stdout_line_count = 5 git rev-list HEAD --max-count=-1 ' test_expect_success '--max-count all forms' ' + test_must_fail git rev-list -1q HEAD 2>error && + grep "not an integer" error && + test_must_fail git rev-list --1 HEAD && + test_must_fail git rev-list -n 1q HEAD 2>error && + grep "not an integer" error && + test_stdout_line_count = 1 git rev-list HEAD --max-count=1 && test_stdout_line_count = 1 git rev-list HEAD -1 && test_stdout_line_count = 1 git rev-list HEAD -n1 && - test_stdout_line_count = 1 git rev-list HEAD -n 1 + test_stdout_line_count = 1 git rev-list HEAD -n 1 && + test_stdout_line_count = 5 git rev-list HEAD -n -1 ' test_expect_success '--skip' ' + test_must_fail git rev-list --skip 1q HEAD 2>error && + grep "not an integer" error && + test_stdout_line_count = 5 git rev-list HEAD --skip=0 && test_stdout_line_count = 2 git rev-list HEAD --skip=3 && test_stdout_line_count = 0 git rev-list HEAD --skip=5 && diff --git a/t/t6009-rev-list-parent.sh b/t/t6009-rev-list-parent.sh index ced40157ed..91db8fafe8 100755 --- a/t/t6009-rev-list-parent.sh +++ b/t/t6009-rev-list-parent.sh @@ -63,6 +63,17 @@ test_expect_success 'setup roots, merges and octopuses' ' git checkout main ' +test_expect_success 'parse --max-parents & --min-parents' ' + test_must_fail git rev-list --max-parents=1q HEAD 2>error && + grep "not an integer" error && + + test_must_fail git rev-list --min-parents=1q HEAD 2>error && + grep "not an integer" error && + + git rev-list --max-parents=1 --min-parents=1 HEAD && + git rev-list --max-parents=-1 --min-parents=-1 HEAD +' + test_expect_success 'rev-list roots' ' check_revlist "--max-parents=0" one five diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index 67d523d405..3b181f771c 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -214,15 +214,13 @@ do for pseudoopt in branches tags remotes do test_expect_success "rev-parse --exclude-hidden=$section fails with --$pseudoopt" ' - echo "error: --exclude-hidden cannot be used together with --$pseudoopt" >expected && test_must_fail git rev-parse --exclude-hidden=$section --$pseudoopt 2>err && - test_cmp expected err + test_grep "error: options .--exclude-hidden. and .--$pseudoopt. cannot be used together" err ' test_expect_success "rev-parse --exclude-hidden=$section fails with --$pseudoopt=pattern" ' - echo "error: --exclude-hidden cannot be used together with --$pseudoopt" >expected && test_must_fail git rev-parse --exclude-hidden=$section --$pseudoopt=pattern 2>err && - test_cmp expected err + test_grep "error: options .--exclude-hidden. and .--$pseudoopt. cannot be used together" err ' done done diff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh index cdf7aa9427..51df02105d 100755 --- a/t/t6021-rev-list-exclude-hidden.sh +++ b/t/t6021-rev-list-exclude-hidden.sh @@ -151,12 +151,12 @@ do do test_expect_success "$section: fails with --$pseudoopt" ' test_must_fail git rev-list --exclude-hidden=$section --$pseudoopt 2>err && - test_grep "error: --exclude-hidden cannot be used together with --$pseudoopt" err + test_grep "error: options .--exclude-hidden. and .--$pseudoopt. cannot be used together" err ' test_expect_success "$section: fails with --$pseudoopt=pattern" ' test_must_fail git rev-list --exclude-hidden=$section --$pseudoopt=pattern 2>err && - test_grep "error: --exclude-hidden cannot be used together with --$pseudoopt" err + test_grep "error: options .--exclude-hidden. and .--$pseudoopt. cannot be used together" err ' done done diff --git a/t/t6022-rev-list-missing.sh b/t/t6022-rev-list-missing.sh index 40265a4f66..211672759a 100755 --- a/t/t6022-rev-list-missing.sh +++ b/t/t6022-rev-list-missing.sh @@ -13,6 +13,12 @@ test_expect_success 'create repository and alternate directory' ' test_commit 3 ' +# We manually corrupt the repository, which means that the commit-graph may +# contain references to already-deleted objects. We thus need to enable +# commit-graph paranoia to not returned these deleted commits from the graph. +GIT_COMMIT_GRAPH_PARANOIA=true +export GIT_COMMIT_GRAPH_PARANOIA + for obj in "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t" do test_expect_success "rev-list --missing=error fails with missing object $obj" ' diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 2a5b7d8379..561080bf24 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -170,6 +170,12 @@ test_expect_success 'bisect reset when not bisecting' ' cmp branch.expect branch.output ' +test_expect_success 'bisect reset cleans up even when not bisecting' ' + echo garbage >.git/BISECT_LOG && + git bisect reset && + test_path_is_missing .git/BISECT_LOG +' + test_expect_success 'bisect reset removes packed refs' ' git bisect reset && git bisect start && @@ -1176,7 +1182,7 @@ test_expect_success 'git bisect reset cleans bisection state properly' ' git bisect bad $HASH4 && git bisect reset && test -z "$(git for-each-ref "refs/bisect/*")" && - test_path_is_missing ".git/BISECT_EXPECTED_REV" && + test_ref_missing BISECT_EXPECTED_REV && test_path_is_missing ".git/BISECT_ANCESTORS_OK" && test_path_is_missing ".git/BISECT_LOG" && test_path_is_missing ".git/BISECT_RUN" && diff --git a/t/t6113-rev-list-bitmap-filters.sh b/t/t6113-rev-list-bitmap-filters.sh index 86c70521f1..a9656a1ec8 100755 --- a/t/t6113-rev-list-bitmap-filters.sh +++ b/t/t6113-rev-list-bitmap-filters.sh @@ -1,9 +1,12 @@ #!/bin/sh test_description='rev-list combining bitmaps and filters' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-bitmap.sh + test_expect_success 'set up bitmapped repo' ' # one commit will have bitmaps, the other will not test_commit one && diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh index a9c1e4e0ec..120dcd74a5 100755 --- a/t/t6135-pathspec-with-attrs.sh +++ b/t/t6135-pathspec-with-attrs.sh @@ -64,12 +64,24 @@ test_expect_success 'setup .gitattributes' ' fileSetLabel label fileValue label=foo fileWrongLabel label☺ + newFileA* labelA + newFileB* labelB EOF echo fileSetLabel label1 >sub/.gitattributes && git add .gitattributes sub/.gitattributes && git commit -m "add attributes" ' +test_expect_success 'setup .gitignore' ' + cat <<-\EOF >.gitignore && + actual + expect + pathspec_file + EOF + git add .gitignore && + git commit -m "add gitignore" +' + test_expect_success 'check specific set attr' ' cat <<-\EOF >expect && fileSetLabel @@ -150,6 +162,7 @@ test_expect_success 'check specific value attr (2)' ' test_expect_success 'check unspecified attr' ' cat <<-\EOF >expect && .gitattributes + .gitignore fileA fileAB fileAC @@ -175,6 +188,7 @@ test_expect_success 'check unspecified attr' ' test_expect_success 'check unspecified attr (2)' ' cat <<-\EOF >expect && HEAD:.gitattributes + HEAD:.gitignore HEAD:fileA HEAD:fileAB HEAD:fileAC @@ -200,6 +214,7 @@ test_expect_success 'check unspecified attr (2)' ' test_expect_success 'check multiple unspecified attr' ' cat <<-\EOF >expect && .gitattributes + .gitignore fileC fileNoLabel fileWrongLabel @@ -239,16 +254,99 @@ test_expect_success 'fail on multiple attr specifiers in one pathspec item' ' test_grep "Only one" actual ' -test_expect_success 'fail if attr magic is used places not implemented' ' +test_expect_success 'fail if attr magic is used in places not implemented' ' # The main purpose of this test is to check that we actually fail # when you attempt to use attr magic in commands that do not implement - # attr magic. This test does not advocate git-add to stay that way, - # though, but git-add is convenient as it has its own internal pathspec - # parsing. - test_must_fail git add ":(attr:labelB)" 2>actual && + # attr magic. This test does not advocate check-ignore to stay that way. + # When you teach the command to grok the pathspec, you need to find + # another command to replace it for the test. + test_must_fail git check-ignore ":(attr:labelB)" 2>actual && test_grep "magic not supported" actual ' +test_expect_success 'check that attr magic works for git stash push' ' + cat <<-\EOF >expect && + A sub/newFileA-foo + EOF + >sub/newFileA-foo && + >sub/newFileB-foo && + git stash push --include-untracked -- ":(exclude,attr:labelB)" && + git stash show --include-untracked --name-status >actual && + test_cmp expect actual +' + +test_expect_success 'check that attr magic works for git add --all' ' + cat <<-\EOF >expect && + sub/newFileA-foo + EOF + >sub/newFileA-foo && + >sub/newFileB-foo && + git add --all ":(exclude,attr:labelB)" && + git diff --name-only --cached >actual && + git restore -W -S . && + test_cmp expect actual +' + +test_expect_success 'check that attr magic works for git add -u' ' + cat <<-\EOF >expect && + sub/fileA + EOF + >sub/newFileA-foo && + >sub/newFileB-foo && + >sub/fileA && + >sub/fileB && + git add -u ":(exclude,attr:labelB)" && + git diff --name-only --cached >actual && + git restore -S -W . && rm sub/new* && + test_cmp expect actual +' + +test_expect_success 'check that attr magic works for git add <path>' ' + cat <<-\EOF >expect && + fileA + fileB + sub/fileA + EOF + >fileA && + >fileB && + >sub/fileA && + >sub/fileB && + git add ":(exclude,attr:labelB)sub/*" && + git diff --name-only --cached >actual && + git restore -S -W . && + test_cmp expect actual +' + +test_expect_success 'check that attr magic works for git -add .' ' + cat <<-\EOF >expect && + sub/fileA + EOF + >fileA && + >fileB && + >sub/fileA && + >sub/fileB && + cd sub && + git add . ":(exclude,attr:labelB)" && + cd .. && + git diff --name-only --cached >actual && + git restore -S -W . && + test_cmp expect actual +' + +test_expect_success 'check that attr magic works for git add --pathspec-from-file' ' + cat <<-\EOF >pathspec_file && + :(exclude,attr:labelB) + EOF + cat <<-\EOF >expect && + sub/newFileA-foo + EOF + >sub/newFileA-foo && + >sub/newFileB-foo && + git add --all --pathspec-from-file=pathspec_file && + git diff --name-only --cached >actual && + test_cmp expect actual +' + test_expect_success 'abort on giving invalid label on the command line' ' test_must_fail git ls-files . ":(attr:☺)" ' @@ -295,4 +393,31 @@ test_expect_success 'reading from .gitattributes in a subdirectory (3)' ' test_cmp expect actual ' +test_expect_success POSIXPERM 'pathspec with builtin_objectmode attr can be used' ' + >mode_exec_file_1 && + + git status -s ":(attr:builtin_objectmode=100644)mode_exec_*" >actual && + echo ?? mode_exec_file_1 >expect && + test_cmp expect actual && + + git add mode_exec_file_1 && + chmod +x mode_exec_file_1 && + git status -s ":(attr:builtin_objectmode=100755)mode_exec_*" >actual && + echo AM mode_exec_file_1 >expect && + test_cmp expect actual +' + +test_expect_success POSIXPERM 'builtin_objectmode attr can be excluded' ' + >mode_1_regular && + >mode_1_exec && + chmod +x mode_1_exec && + git status -s ":(exclude,attr:builtin_objectmode=100644)" "mode_1_*" >actual && + echo ?? mode_1_exec >expect && + test_cmp expect actual && + + git status -s ":(exclude,attr:builtin_objectmode=100755)" "mode_1_*" >actual && + echo ?? mode_1_regular >expect && + test_cmp expect actual +' + test_done diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 00a060df0b..eb6c8204e8 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -20,12 +20,13 @@ setdate_and_increment () { export GIT_COMMITTER_DATE GIT_AUTHOR_DATE } -test_expect_success setup ' - test_oid_cache <<-EOF && - disklen sha1:138 - disklen sha256:154 - EOF +test_object_file_size () { + oid=$(git rev-parse "$1") + path=".git/objects/$(test_oid_to_path $oid)" + test_file_size "$path" +} +test_expect_success setup ' # setup .mailmap cat >.mailmap <<-EOF && A Thor <athor@example.com> A U Thor <author@example.com> @@ -94,7 +95,6 @@ test_atom () { } hexlen=$(test_oid hexsz) -disklen=$(test_oid disklen) test_atom head refname refs/heads/main test_atom head refname: refs/heads/main @@ -129,7 +129,7 @@ test_atom head push:strip=1 remotes/myfork/main test_atom head push:strip=-1 main test_atom head objecttype commit test_atom head objectsize $((131 + hexlen)) -test_atom head objectsize:disk $disklen +test_atom head objectsize:disk $(test_object_file_size refs/heads/main) test_atom head deltabase $ZERO_OID test_atom head objectname $(git rev-parse refs/heads/main) test_atom head objectname:short $(git rev-parse --short refs/heads/main) @@ -203,8 +203,8 @@ test_atom tag upstream '' test_atom tag push '' test_atom tag objecttype tag test_atom tag objectsize $((114 + hexlen)) -test_atom tag objectsize:disk $disklen -test_atom tag '*objectsize:disk' $disklen +test_atom tag objectsize:disk $(test_object_file_size refs/tags/testtag) +test_atom tag '*objectsize:disk' $(test_object_file_size refs/heads/main) test_atom tag deltabase $ZERO_OID test_atom tag '*deltabase' $ZERO_OID test_atom tag objectname $(git rev-parse refs/tags/testtag) @@ -1335,6 +1335,73 @@ test_expect_success '--no-sort cancels the previous sort keys' ' test_cmp expected actual ' +test_expect_success '--no-sort without subsequent --sort prints expected refs' ' + cat >expected <<-\EOF && + refs/tags/multi-ref1-100000-user1 + refs/tags/multi-ref1-100000-user2 + refs/tags/multi-ref1-200000-user1 + refs/tags/multi-ref1-200000-user2 + refs/tags/multi-ref2-100000-user1 + refs/tags/multi-ref2-100000-user2 + refs/tags/multi-ref2-200000-user1 + refs/tags/multi-ref2-200000-user2 + EOF + + # Sort the results with `sort` for a consistent comparison against + # expected + git for-each-ref \ + --format="%(refname)" \ + --no-sort \ + "refs/tags/multi-*" | sort >actual && + test_cmp expected actual +' + +test_expect_success 'set up custom date sorting' ' + # Dates: + # - Wed Feb 07 2024 21:34:20 +0000 + # - Tue Dec 14 1999 00:05:22 +0000 + # - Fri Jun 04 2021 11:26:51 +0000 + # - Mon Jan 22 2007 16:44:01 GMT+0000 + i=1 && + for when in 1707341660 945129922 1622806011 1169484241 + do + GIT_COMMITTER_DATE="@$when +0000" \ + GIT_COMMITTER_EMAIL="user@example.com" \ + git tag -m "tag $when" custom-dates-$i && + i=$(($i+1)) || return 1 + done +' + +test_expect_success 'sort by date defaults to full timestamp' ' + cat >expected <<-\EOF && + 945129922 refs/tags/custom-dates-2 + 1169484241 refs/tags/custom-dates-4 + 1622806011 refs/tags/custom-dates-3 + 1707341660 refs/tags/custom-dates-1 + EOF + + git for-each-ref \ + --format="%(creatordate:unix) %(refname)" \ + --sort=creatordate \ + "refs/tags/custom-dates-*" >actual && + test_cmp expected actual +' + +test_expect_success 'sort by custom date format' ' + cat >expected <<-\EOF && + 00:05:22 refs/tags/custom-dates-2 + 11:26:51 refs/tags/custom-dates-3 + 16:44:01 refs/tags/custom-dates-4 + 21:34:20 refs/tags/custom-dates-1 + EOF + + git for-each-ref \ + --format="%(creatordate:format:%H:%M:%S) %(refname)" \ + --sort="creatordate:format:%H:%M:%S" \ + "refs/tags/custom-dates-*" >actual && + test_cmp expected actual +' + test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' test_when_finished "git checkout main" && git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual && @@ -1818,6 +1885,28 @@ test_expect_success 'git for-each-ref with non-existing refs' ' test_must_be_empty actual ' +test_expect_success 'git for-each-ref with nested tags' ' + git tag -am "Normal tag" nested/base HEAD && + git tag -am "Nested tag" nested/nest1 refs/tags/nested/base && + git tag -am "Double nested tag" nested/nest2 refs/tags/nested/nest1 && + + head_oid="$(git rev-parse HEAD)" && + base_tag_oid="$(git rev-parse refs/tags/nested/base)" && + nest1_tag_oid="$(git rev-parse refs/tags/nested/nest1)" && + nest2_tag_oid="$(git rev-parse refs/tags/nested/nest2)" && + + cat >expect <<-EOF && + refs/tags/nested/base $base_tag_oid tag $head_oid commit + refs/tags/nested/nest1 $nest1_tag_oid tag $head_oid commit + refs/tags/nested/nest2 $nest2_tag_oid tag $head_oid commit + EOF + + git for-each-ref \ + --format="%(refname) %(objectname) %(objecttype) %(*objectname) %(*objecttype)" \ + refs/tags/nested/ >actual && + test_cmp expect actual +' + GRADE_FORMAT="%(signature:grade)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" TRUSTLEVEL_FORMAT="%(signature:trustlevel)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" diff --git a/t/t6301-for-each-ref-errors.sh b/t/t6301-for-each-ref-errors.sh index 2667dd13fe..83b8a19d94 100755 --- a/t/t6301-for-each-ref-errors.sh +++ b/t/t6301-for-each-ref-errors.sh @@ -15,7 +15,7 @@ test_expect_success setup ' git for-each-ref --format="%(objectname) %(refname)" >brief-list ' -test_expect_success 'Broken refs are reported correctly' ' +test_expect_success REFFILES 'Broken refs are reported correctly' ' r=refs/heads/bogus && : >.git/$r && test_when_finished "rm -f .git/$r" && @@ -25,7 +25,7 @@ test_expect_success 'Broken refs are reported correctly' ' test_cmp broken-err err ' -test_expect_success 'NULL_SHA1 refs are reported correctly' ' +test_expect_success REFFILES 'NULL_SHA1 refs are reported correctly' ' r=refs/heads/zeros && echo $ZEROS >.git/$r && test_when_finished "rm -f .git/$r" && @@ -39,15 +39,14 @@ test_expect_success 'NULL_SHA1 refs are reported correctly' ' ' test_expect_success 'Missing objects are reported correctly' ' - r=refs/heads/missing && - echo $MISSING >.git/$r && - test_when_finished "rm -f .git/$r" && - echo "fatal: missing object $MISSING for $r" >missing-err && + test_when_finished "git update-ref -d refs/heads/missing" && + test-tool ref-store main update-ref msg refs/heads/missing "$MISSING" "$ZERO_OID" REF_SKIP_OID_VERIFICATION && + echo "fatal: missing object $MISSING for refs/heads/missing" >missing-err && test_must_fail git for-each-ref 2>err && test_cmp missing-err err && ( cat brief-list && - echo "$MISSING $r" + echo "$MISSING refs/heads/missing" ) | sort -k 2 >missing-brief-expected && git for-each-ref --format="%(objectname) %(refname)" >brief-out 2>brief-err && test_cmp missing-brief-expected brief-out && diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index af223e44d6..948f1bb5f4 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -31,6 +31,37 @@ test_expect_success 'setup some history and refs' ' git update-ref refs/odd/spot main ' +test_expect_success '--include-root-refs pattern prints pseudorefs' ' + cat >expect <<-\EOF && + HEAD + ORIG_HEAD + refs/heads/main + refs/heads/side + refs/odd/spot + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git update-ref ORIG_HEAD main && + git for-each-ref --format="%(refname)" --include-root-refs >actual && + test_cmp expect actual +' + +test_expect_success '--include-root-refs with other patterns' ' + cat >expect <<-\EOF && + HEAD + ORIG_HEAD + EOF + git update-ref ORIG_HEAD main && + git for-each-ref --format="%(refname)" --include-root-refs "*HEAD" >actual && + test_cmp expect actual +' + test_expect_success 'filtering with --points-at' ' cat >expect <<-\EOF && refs/heads/main @@ -45,8 +76,8 @@ test_expect_success 'check signed tags with --points-at' ' sed -e "s/Z$//" >expect <<-\EOF && refs/heads/side Z refs/tags/annotated-tag four - refs/tags/doubly-annotated-tag An annotated tag - refs/tags/doubly-signed-tag A signed tag + refs/tags/doubly-annotated-tag four + refs/tags/doubly-signed-tag four refs/tags/four Z refs/tags/signed-tag four EOF diff --git a/t/t6403-merge-file.sh b/t/t6403-merge-file.sh index 2c92209eca..fb872c5a11 100755 --- a/t/t6403-merge-file.sh +++ b/t/t6403-merge-file.sh @@ -56,7 +56,67 @@ test_expect_success 'setup' ' deduxit me super semitas jusitiae, EOF - printf "propter nomen suum." >>new4.txt + printf "propter nomen suum." >>new4.txt && + + cat >base.c <<-\EOF && + int f(int x, int y) + { + if (x == 0) + { + return y; + } + return x; + } + + int g(size_t u) + { + while (u < 30) + { + u++; + } + return u; + } + EOF + + cat >ours.c <<-\EOF && + int g(size_t u) + { + while (u < 30) + { + u++; + } + return u; + } + + int h(int x, int y, int z) + { + if (z == 0) + { + return x; + } + return y; + } + EOF + + cat >theirs.c <<-\EOF + int f(int x, int y) + { + if (x == 0) + { + return y; + } + return x; + } + + int g(size_t u) + { + while (u > 34) + { + u--; + } + return u; + } + EOF ' test_expect_success 'merge with no changes' ' @@ -447,4 +507,66 @@ test_expect_success '--object-id fails without repository' ' grep "not a git repository" err ' +test_expect_success 'merging C files with "myers" diff algorithm creates some spurious conflicts' ' + cat >expect.c <<-\EOF && + int g(size_t u) + { + while (u < 30) + { + u++; + } + return u; + } + + int h(int x, int y, int z) + { + <<<<<<< ours.c + if (z == 0) + ||||||| base.c + while (u < 30) + ======= + while (u > 34) + >>>>>>> theirs.c + { + <<<<<<< ours.c + return x; + ||||||| base.c + u++; + ======= + u--; + >>>>>>> theirs.c + } + return y; + } + EOF + + test_must_fail git merge-file -p --diff3 --diff-algorithm myers ours.c base.c theirs.c >myers_output.c && + test_cmp expect.c myers_output.c +' + +test_expect_success 'merging C files with "histogram" diff algorithm avoids some spurious conflicts' ' + cat >expect.c <<-\EOF && + int g(size_t u) + { + while (u > 34) + { + u--; + } + return u; + } + + int h(int x, int y, int z) + { + if (z == 0) + { + return x; + } + return y; + } + EOF + + git merge-file -p --diff3 --diff-algorithm histogram ours.c base.c theirs.c >histogram_output.c && + test_cmp expect.c histogram_output.c +' + test_done diff --git a/t/t6406-merge-attr.sh b/t/t6406-merge-attr.sh index 72f8c1722f..156a1efacf 100755 --- a/t/t6406-merge-attr.sh +++ b/t/t6406-merge-attr.sh @@ -42,11 +42,15 @@ test_expect_success setup ' #!/bin/sh orig="$1" ours="$2" theirs="$3" exit="$4" path=$5 + orig_name="$6" our_name="$7" their_name="$8" ( echo "orig is $orig" echo "ours is $ours" echo "theirs is $theirs" echo "path is $path" + echo "orig_name is $orig_name" + echo "our_name is $our_name" + echo "their_name is $their_name" echo "=== orig ===" cat "$orig" echo "=== ours ===" @@ -121,7 +125,7 @@ test_expect_success 'custom merge backend' ' git reset --hard anchor && git config --replace-all \ - merge.custom.driver "./custom-merge %O %A %B 0 %P" && + merge.custom.driver "./custom-merge %O %A %B 0 %P %S %X %Y" && git config --replace-all \ merge.custom.name "custom merge driver for testing" && @@ -132,7 +136,8 @@ test_expect_success 'custom merge backend' ' o=$(git unpack-file main^:text) && a=$(git unpack-file side^:text) && b=$(git unpack-file main:text) && - sh -c "./custom-merge $o $a $b 0 text" && + base_revid=$(git rev-parse --short main^) && + sh -c "./custom-merge $o $a $b 0 text $base_revid HEAD main" && sed -e 1,3d $a >check-2 && cmp check-1 check-2 && rm -f $o $a $b @@ -142,7 +147,7 @@ test_expect_success 'custom merge backend' ' git reset --hard anchor && git config --replace-all \ - merge.custom.driver "./custom-merge %O %A %B 1 %P" && + merge.custom.driver "./custom-merge %O %A %B 1 %P %S %X %Y" && git config --replace-all \ merge.custom.name "custom merge driver for testing" && @@ -159,7 +164,8 @@ test_expect_success 'custom merge backend' ' o=$(git unpack-file main^:text) && a=$(git unpack-file anchor:text) && b=$(git unpack-file main:text) && - sh -c "./custom-merge $o $a $b 0 text" && + base_revid=$(git rev-parse --short main^) && + sh -c "./custom-merge $o $a $b 0 text $base_revid HEAD main" && sed -e 1,3d $a >check-2 && cmp check-1 check-2 && sed -e 1,3d -e 4q $a >check-3 && @@ -173,7 +179,7 @@ test_expect_success !WINDOWS 'custom merge driver that is killed with a signal' git reset --hard anchor && git config --replace-all \ - merge.custom.driver "./custom-merge %O %A %B 0 %P" && + merge.custom.driver "./custom-merge %O %A %B 0 %P %S %X %Y" && git config --replace-all \ merge.custom.name "custom merge driver for testing" && diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh index d02fa16614..0f39ed0d08 100755 --- a/t/t6429-merge-sequence-rename-caching.sh +++ b/t/t6429-merge-sequence-rename-caching.sh @@ -71,8 +71,9 @@ test_expect_success 'caching renames does not preclude finding new ones' ' git switch upstream && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream~1..topic + git replay --onto HEAD upstream~1..topic >out && + git update-ref --stdin <out && + git checkout topic && git ls-files >tracked-files && test_line_count = 2 tracked-files && @@ -140,8 +141,9 @@ test_expect_success 'cherry-pick both a commit and its immediate revert' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream~1..topic && + git replay --onto HEAD upstream~1..topic >out && + git update-ref --stdin <out && + git checkout topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 1 calls @@ -199,8 +201,9 @@ test_expect_success 'rename same file identically, then reintroduce it' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream~1..topic && + git replay --onto HEAD upstream~1..topic >out && + git update-ref --stdin <out && + git checkout topic && git ls-files >tracked && test_line_count = 2 tracked && @@ -276,8 +279,9 @@ test_expect_success 'rename same file identically, then add file to old dir' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream~1..topic && + git replay --onto HEAD upstream~1..topic >out && + git update-ref --stdin <out && + git checkout topic && git ls-files >tracked && test_line_count = 4 tracked && @@ -353,10 +357,7 @@ test_expect_success 'cached dir rename does not prevent noticing later conflict' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test_must_fail test-tool fast-rebase --onto HEAD upstream~1 topic >output && - #git cherry-pick upstream..topic && - - grep CONFLICT..rename/rename output && + test_must_fail git replay --onto HEAD upstream~1..topic >output && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 2 calls @@ -455,8 +456,9 @@ test_expect_success 'dir rename unneeded, then add new file to old dir' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream..topic && + git replay --onto HEAD upstream~1..topic >out && + git update-ref --stdin <out && + git checkout topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 2 calls && @@ -521,8 +523,9 @@ test_expect_success 'dir rename unneeded, then rename existing file into old dir GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream..topic && + git replay --onto HEAD upstream~1..topic >out && + git update-ref --stdin <out && + git checkout topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 3 calls && @@ -623,8 +626,9 @@ test_expect_success 'caching renames only on upstream side, part 1' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream..topic && + git replay --onto HEAD upstream~1..topic >out && + git update-ref --stdin <out && + git checkout topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 1 calls && @@ -681,8 +685,9 @@ test_expect_success 'caching renames only on upstream side, part 2' ' GIT_TRACE2_PERF="$(pwd)/trace.output" && export GIT_TRACE2_PERF && - test-tool fast-rebase --onto HEAD upstream~1 topic && - #git cherry-pick upstream..topic && + git replay --onto HEAD upstream~1..topic >out && + git update-ref --stdin <out && + git checkout topic && grep region_enter.*diffcore_rename trace.output >calls && test_line_count = 2 calls && diff --git a/t/t6437-submodule-merge.sh b/t/t6437-submodule-merge.sh index 70650521b0..7a3f1cb27c 100755 --- a/t/t6437-submodule-merge.sh +++ b/t/t6437-submodule-merge.sh @@ -113,7 +113,7 @@ test_expect_success 'merging should conflict for non fast-forward' ' git checkout -b test-nonforward-a b && if test "$GIT_TEST_MERGE_ALGORITHM" = ort then - test_must_fail git merge c >actual && + test_must_fail git merge c 2>actual && sub_expect="go to submodule (sub), and either merge commit $(git -C sub rev-parse --short sub-c)" && grep "$sub_expect" actual else @@ -154,9 +154,9 @@ test_expect_success 'merging should conflict for non fast-forward (resolution ex git rev-parse --short sub-d > ../expect) && if test "$GIT_TEST_MERGE_ALGORITHM" = ort then - test_must_fail git merge c >actual && + test_must_fail git merge c >actual 2>sub-actual && sub_expect="go to submodule (sub), and either merge commit $(git -C sub rev-parse --short sub-c)" && - grep "$sub_expect" actual + grep "$sub_expect" sub-actual else test_must_fail git merge c 2> actual fi && @@ -181,9 +181,9 @@ test_expect_success 'merging should fail for ambiguous common parent' ' ) && if test "$GIT_TEST_MERGE_ALGORITHM" = ort then - test_must_fail git merge c >actual && + test_must_fail git merge c >actual 2>sub-actual && sub_expect="go to submodule (sub), and either merge commit $(git -C sub rev-parse --short sub-c)" && - grep "$sub_expect" actual + grep "$sub_expect" sub-actual else test_must_fail git merge c 2> actual fi && @@ -227,7 +227,7 @@ test_expect_success 'merging should fail for changes that are backwards' ' git commit -a -m "f" && git checkout -b test-backward e && - test_must_fail git merge f >actual && + test_must_fail git merge f 2>actual && if test "$GIT_TEST_MERGE_ALGORITHM" = ort then sub_expect="go to submodule (sub), and either merge commit $(git -C sub rev-parse --short sub-d)" && @@ -535,7 +535,7 @@ test_expect_success 'merging should fail with no merge base' ' git checkout -b b init && git add sub && git commit -m "b" && - test_must_fail git merge a >actual && + test_must_fail git merge a 2>actual && if test "$GIT_TEST_MERGE_ALGORITHM" = ort then sub_expect="go to submodule (sub), and either merge commit $(git -C sub rev-parse --short HEAD^1)" && diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index f6aebe92ff..5ab4d41ee7 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -396,10 +396,7 @@ test_expect_success '--prune-empty is able to prune entire branch' ' git branch prune-entire B && git filter-branch -f --prune-empty --index-filter "git update-index --remove A.t B.t" prune-entire && test_must_fail git rev-parse refs/heads/prune-entire && - if test_have_prereq REFFILES - then - test_must_fail git reflog exists refs/heads/prune-entire - fi + test_must_fail git reflog exists refs/heads/prune-entire ' test_expect_success '--remap-to-ancestor with filename filters' ' diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index e689db4292..b41a47eb94 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1862,6 +1862,51 @@ test_expect_success 'option override configured sort' ' test_cmp expect actual ' +test_expect_success '--no-sort cancels config sort keys' ' + test_config tag.sort "-refname" && + + # objecttype is identical for all of them, so sort falls back on + # default (ascending refname) + git tag -l \ + --no-sort \ + --sort="objecttype" \ + "foo*" >actual && + cat >expect <<-\EOF && + foo1.10 + foo1.3 + foo1.6 + EOF + test_cmp expect actual +' + +test_expect_success '--no-sort cancels command line sort keys' ' + # objecttype is identical for all of them, so sort falls back on + # default (ascending refname) + git tag -l \ + --sort="-refname" \ + --no-sort \ + --sort="objecttype" \ + "foo*" >actual && + cat >expect <<-\EOF && + foo1.10 + foo1.3 + foo1.6 + EOF + test_cmp expect actual +' + +test_expect_success '--no-sort without subsequent --sort prints expected tags' ' + # Sort the results with `sort` for a consistent comparison against + # expected + git tag -l --no-sort "foo*" | sort >actual && + cat >expect <<-\EOF && + foo1.10 + foo1.3 + foo1.6 + EOF + test_cmp expect actual +' + test_expect_success 'invalid sort parameter on command line' ' test_must_fail git tag -l --sort=notvalid "foo*" >actual ' diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 4287863ae6..62d9f846ce 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -616,4 +616,12 @@ test_expect_success 'reset --mixed sets up work tree' ' test_must_be_empty actual ' +test_expect_success 'reset handles --end-of-options' ' + git update-ref refs/heads/--foo HEAD^ && + git log -1 --format=%s refs/heads/--foo >expect && + git reset --hard --end-of-options --foo && + git log -1 --format=%s HEAD >actual && + test_cmp expect actual +' + test_done diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh index 05079c7246..f4f3b7a677 100755 --- a/t/t7105-reset-patch.sh +++ b/t/t7105-reset-patch.sh @@ -5,7 +5,7 @@ test_description='git reset --patch' TEST_PASSES_SANITIZE_LEAK=true . ./lib-patch-mode.sh -test_expect_success PERL 'setup' ' +test_expect_success 'setup' ' mkdir dir && echo parent > dir/foo && echo dummy > bar && @@ -19,42 +19,46 @@ test_expect_success PERL 'setup' ' # note: bar sorts before foo, so the first 'n' is always to skip 'bar' -test_expect_success PERL 'saying "n" does nothing' ' +test_expect_success 'saying "n" does nothing' ' set_and_save_state dir/foo work work && test_write_lines n n | git reset -p && verify_saved_state dir/foo && verify_saved_state bar ' -test_expect_success PERL 'git reset -p' ' - test_write_lines n y | git reset -p >output && - verify_state dir/foo work head && - verify_saved_state bar && - test_grep "Unstage" output -' - -test_expect_success PERL 'git reset -p HEAD^' ' +for opt in "HEAD" "@" "" +do + test_expect_success "git reset -p $opt" ' + set_and_save_state dir/foo work work && + test_write_lines n y | git reset -p $opt >output && + verify_state dir/foo work head && + verify_saved_state bar && + test_grep "Unstage" output + ' +done + +test_expect_success 'git reset -p HEAD^' ' test_write_lines n y | git reset -p HEAD^ >output && verify_state dir/foo work parent && verify_saved_state bar && test_grep "Apply" output ' -test_expect_success PERL 'git reset -p HEAD^^{tree}' ' +test_expect_success 'git reset -p HEAD^^{tree}' ' test_write_lines n y | git reset -p HEAD^^{tree} >output && verify_state dir/foo work parent && verify_saved_state bar && test_grep "Apply" output ' -test_expect_success PERL 'git reset -p HEAD^:dir/foo (blob fails)' ' +test_expect_success 'git reset -p HEAD^:dir/foo (blob fails)' ' set_and_save_state dir/foo work work && test_must_fail git reset -p HEAD^:dir/foo && verify_saved_state dir/foo && verify_saved_state bar ' -test_expect_success PERL 'git reset -p aaaaaaaa (unknown fails)' ' +test_expect_success 'git reset -p aaaaaaaa (unknown fails)' ' set_and_save_state dir/foo work work && test_must_fail git reset -p aaaaaaaa && verify_saved_state dir/foo && @@ -66,27 +70,27 @@ test_expect_success PERL 'git reset -p aaaaaaaa (unknown fails)' ' # 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 'git reset -p dir' ' +test_expect_success 'git reset -p dir' ' set_state dir/foo work work && test_write_lines y n | git reset -p dir && verify_state dir/foo work head && verify_saved_state bar ' -test_expect_success PERL 'git reset -p -- foo (inside dir)' ' +test_expect_success 'git reset -p -- foo (inside dir)' ' set_state dir/foo work work && test_write_lines y n | (cd dir && git reset -p -- foo) && verify_state dir/foo work head && verify_saved_state bar ' -test_expect_success PERL 'git reset -p HEAD^ -- dir' ' +test_expect_success 'git reset -p HEAD^ -- dir' ' test_write_lines y n | git reset -p HEAD^ -- dir && verify_state dir/foo work parent && verify_saved_state bar ' -test_expect_success PERL 'none of this moved HEAD' ' +test_expect_success 'none of this moved HEAD' ' verify_saved_head ' diff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh index d20e5709f9..88d1c8adf4 100755 --- a/t/t7106-reset-unborn-branch.sh +++ b/t/t7106-reset-unborn-branch.sh @@ -34,7 +34,7 @@ test_expect_success 'reset $file' ' test_cmp expect actual ' -test_expect_success PERL 'reset -p' ' +test_expect_success 'reset -p' ' rm .git/index && git add a && echo y >yes && diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 1a310a45fd..611b3dd3ae 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -517,8 +517,12 @@ test_expect_success 'nested (empty) git should be kept' ' git init empty_repo && mkdir to_clean && >to_clean/should_clean.this && + # Note that we put the expect file in the .git directory so that it + # does not get cleaned. + find empty_repo | sort >.git/expect && git clean -f -d && - test_path_is_file empty_repo/.git/HEAD && + find empty_repo | sort >actual && + test_cmp .git/expect actual && test_path_is_missing to_clean ' @@ -559,10 +563,10 @@ test_expect_success 'giving path in nested git work tree will NOT remove it' ' mkdir -p bar/baz && test_commit msg bar/baz/hello.world ) && + find repo | sort >expect && git clean -f -d repo/bar/baz && - test_path_is_file repo/.git/HEAD && - test_path_is_dir repo/bar/ && - test_path_is_file repo/bar/baz/hello.world + find repo | sort >actual && + test_cmp expect actual ' test_expect_success 'giving path to nested .git will not remove it' ' @@ -573,10 +577,10 @@ test_expect_success 'giving path to nested .git will not remove it' ' git init && test_commit msg hello.world ) && + find repo | sort >expect && git clean -f -d repo/.git && - test_path_is_file repo/.git/HEAD && - test_path_is_dir repo/.git/refs && - test_path_is_dir repo/.git/objects && + find repo | sort >actual && + test_cmp expect actual && test_path_is_dir untracked/ ' @@ -588,9 +592,10 @@ test_expect_success 'giving path to nested .git/ will NOT remove contents' ' git init && test_commit msg hello.world ) && + find repo | sort >expect && git clean -f -d repo/.git/ && - test_path_is_dir repo/.git && - test_path_is_file repo/.git/HEAD && + find repo | sort >actual && + test_cmp expect actual && test_path_is_dir untracked/ ' diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh index 2b3c363078..aa2fdc31d1 100755 --- a/t/t7402-submodule-rebase.sh +++ b/t/t7402-submodule-rebase.sh @@ -116,7 +116,7 @@ test_expect_success 'rebasing submodule that should conflict' ' test_tick && git commit -m fourth && - test_must_fail git rebase --onto HEAD^^ HEAD^ HEAD^0 >actual_output && + test_must_fail git rebase --onto HEAD^^ HEAD^ HEAD^0 2>actual_output && git ls-files -s submodule >actual && ( cd submodule && diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh index 35a31acd4d..46d4fb0354 100755 --- a/t/t7450-bad-git-dotfiles.sh +++ b/t/t7450-bad-git-dotfiles.sh @@ -45,6 +45,32 @@ test_expect_success 'check names' ' test_cmp expect actual ' +test_expect_success 'check urls' ' + cat >expect <<-\EOF && + ./bar/baz/foo.git + https://example.com/foo.git + http://example.com:80/deeper/foo.git + EOF + + test-tool submodule check-url >actual <<-\EOF && + ./bar/baz/foo.git + https://example.com/foo.git + http://example.com:80/deeper/foo.git + -a./foo + ../../..//test/foo.git + ../../../../../:localhost:8080/foo.git + ..\../.\../:example.com/foo.git + ./%0ahost=example.com/foo.git + https://one.example.com/evil?%0ahost=two.example.com + https:///example.com/foo.git + http://example.com:test/foo.git + https::example.com/foo.git + http:::example.com/foo.git + EOF + + test_cmp expect actual +' + test_expect_success 'create innocent subrepo' ' git init innocent && git -C innocent commit --allow-empty -m foo diff --git a/t/t7501-commit-basic-functionality.sh b/t/t7501-commit-basic-functionality.sh index 3d8500a52e..bced44a0fc 100755 --- a/t/t7501-commit-basic-functionality.sh +++ b/t/t7501-commit-basic-functionality.sh @@ -3,8 +3,7 @@ # Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com> # -# FIXME: Test the various index usages, -i and -o, test reflog, -# signoff +# FIXME: Test the various index usages, test reflog test_description='git commit' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main @@ -92,6 +91,34 @@ test_expect_success '--long fails with nothing to commit' ' test_must_fail git commit -m initial --long ' +test_expect_success 'fail to commit untracked file (even with --include/--only)' ' + echo content >baz && + error="error: pathspec .baz. did not match any file(s) known to git" && + + test_must_fail git commit -m "baz" baz 2>err && + test_grep -e "$error" err && + + test_must_fail git commit --only -m "baz" baz 2>err && + test_grep -e "$error" err && + + # TODO: as for --include, the below command will fail because + # nothing is staged. If something was staged, it would not fail + # even though the provided pathspec does not match any tracked + # path. (However, the untracked paths that match the pathspec are + # not committed and only the staged changes get committed.) + # In either cases, no error is returned to stderr like in (--only + # and without --only/--include) cases. In a similar manner, + # "git add -u baz" also does not error out. + # + # Therefore, the below test is just to document the current behavior + # and is not an endorsement to the current behavior, and we may + # want to fix this. And when that happens, this test should be + # updated accordingly. + + test_must_fail git commit --include -m "baz" baz 2>err && + test_must_be_empty err +' + test_expect_success 'setup: non-initial commit' ' echo bongo bongo bongo >file && git commit -m next -a @@ -117,6 +144,51 @@ test_expect_success '--long with stuff to commit returns ok' ' git commit -m next -a --long ' +for opt in "" "-o" "--only" +do + test_expect_success 'exclude additional staged changes when given pathspec' ' + echo content >>file && + echo content >>baz && + git add baz && + git commit $opt -m "file" file && + + git diff --name-only >actual && + test_must_be_empty actual && + + test_write_lines baz >expect && + git diff --name-only --cached >actual && + test_cmp expect actual && + + test_write_lines file >expect && + git diff --name-only HEAD^ HEAD >actual && + test_cmp expect actual + ' +done + +test_expect_success '-i/--include includes staged changes' ' + echo content >>file && + echo content >>baz && + git add file && + + # baz is in the index, therefore, it will be committed + git commit --include -m "file and baz" baz && + + git diff --name-only HEAD >remaining && + test_must_be_empty remaining && + + test_write_lines baz file >expect && + git diff --name-only HEAD^ HEAD >actual && + test_cmp expect actual +' + +test_expect_success '--include and --only do not mix' ' + test_when_finished "git reset --hard" && + echo content >>file && + echo content >>baz && + test_must_fail git commit --include --only -m "file baz" file baz 2>actual && + test_grep -e "fatal: options .-i/--include. and .-o/--only. cannot be used together" actual +' + test_expect_success 'commit message from non-existing file' ' echo more bongo: bongo bongo bongo bongo >file && test_must_fail git commit -F gah -a @@ -389,6 +461,28 @@ test_expect_success 'amend commit to fix date' ' ' +test_expect_success 'amend commit to add signoff' ' + + test_commit "msg" file content && + git commit --amend --signoff && + test_commit_message HEAD <<-EOF + msg + + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF +' + +test_expect_success 'amend does not add signoff if it already exists' ' + + test_commit --signoff "tenor" file newcontent && + git commit --amend --signoff && + test_commit_message HEAD <<-EOF + tenor + + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF +' + test_expect_success 'commit mentions forced date in output' ' git commit --amend --date=2010-01-02T03:04:05 >output && grep "Date: *Sat Jan 2 03:04:05 2010" output diff --git a/t/t7502-commit-porcelain.sh b/t/t7502-commit-porcelain.sh index 61c8e810cc..a87c211d0b 100755 --- a/t/t7502-commit-porcelain.sh +++ b/t/t7502-commit-porcelain.sh @@ -485,6 +485,24 @@ test_expect_success 'commit --trailer not confused by --- separator' ' test_cmp expected actual ' +test_expect_success 'commit --trailer with --verbose' ' + cat >msg <<-\EOF && + subject + + body + EOF + GIT_EDITOR=: git commit --edit -F msg --allow-empty \ + --trailer="my-trailer: value" --verbose && + { + cat msg && + echo && + echo "my-trailer: value" + } >expected && + git cat-file commit HEAD >commit.msg && + sed -e "1,/^\$/d" commit.msg >actual && + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative && diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index c2ab8a444a..802f8f704c 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -692,6 +692,34 @@ EOF ' +test_expect_success 'status when bisecting while rebasing' ' + git reset --hard main && + test_when_finished "git rebase --abort" && + ONTO=$(git rev-parse --short HEAD^) && + FAKE_LINES="break" git rebase -i HEAD^ && + test_when_finished "git checkout -" && + git checkout -b bisect_while_rebasing && + test_when_finished "git bisect reset" && + git bisect start && + cat >expected <<EOF && +On branch bisect_while_rebasing +Last command done (1 command done): + break +No commands remaining. +You are currently editing a commit while rebasing branch '\''bisect'\'' on '\''$ONTO'\''. + (use "git commit --amend" to amend the current commit) + (use "git rebase --continue" once you are satisfied with your changes) + +You are currently bisecting, started from branch '\''bisect_while_rebasing'\''. + (use "git bisect reset" to get back to the original branch) + +nothing to commit (use -u to show untracked files) +EOF + git status --untracked-files=no >actual && + test_cmp expected actual +' + + test_expect_success 'status when rebase --apply conflicts with statushints disabled' ' git reset --hard main && git checkout -b statushints_disabled && diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh index 832aff0616..ec9c6de114 100755 --- a/t/t7513-interpret-trailers.sh +++ b/t/t7513-interpret-trailers.sh @@ -1916,4 +1916,23 @@ test_expect_success 'suppress --- handling' ' test_cmp expected actual ' +test_expect_success 'suppressing --- does not disable cut-line handling' ' + echo "real-trailer: before the cut" >expected && + + git interpret-trailers --parse --no-divider >actual <<-\EOF && + subject + + This input has a cut-line in it; we should stop parsing when we see it + and consider only trailers before that line. + + real-trailer: before the cut + + # ------------------------ >8 ------------------------ + # Nothing below this line counts as part of the commit message. + not-a-trailer: too late + EOF + + test_cmp expected actual +' + test_done diff --git a/t/t7514-commit-patch.sh b/t/t7514-commit-patch.sh index 998a2103c7..b4de10a5dd 100755 --- a/t/t7514-commit-patch.sh +++ b/t/t7514-commit-patch.sh @@ -3,12 +3,6 @@ test_description='hunk edit with "commit -p -m"' . ./test-lib.sh -if ! test_have_prereq PERL -then - skip_all="skipping '$test_description' tests, perl not available" - test_done -fi - test_expect_success 'setup (initial)' ' echo line1 >file && git add file && diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh index 78503158fd..363f9dc0e4 100755 --- a/t/t7527-builtin-fsmonitor.sh +++ b/t/t7527-builtin-fsmonitor.sh @@ -978,7 +978,7 @@ test_expect_success !UNICODE_COMPOSITION_SENSITIVE 'Unicode nfc/nfd' ' mkdir test_unicode/nfd && mkdir test_unicode/nfd/d_${utf8_nfd} && - git -C test_unicode fsmonitor--daemon stop && + test-tool -C test_unicode fsmonitor-client query --token 0 && if test_have_prereq UNICODE_NFC_PRESERVED then diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index d2975e6c93..94f9f4a1da 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -271,7 +271,7 @@ test_expect_success 'repacking fails when missing .pack actually means missing o ls .git/objects/pack/*.pack >before-pack-dir && test_must_fail git fsck && - test_must_fail git repack --cruft -d 2>err && + test_must_fail env GIT_COMMIT_GRAPH_PARANOIA=true git repack --cruft -d 2>err && grep "bad object" err && # Before failing, the repack did not modify the diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 6a36be1e63..96ae5d5880 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -91,58 +91,67 @@ test_expect_success 'difftool forwards arguments to diff' ' rm for-diff ' -test_expect_success 'difftool ignores exit code' ' - test_config difftool.error.cmd false && - git difftool -y -t error branch -' +for opt in '' '--dir-diff' +do + test_expect_success "difftool ${opt} ignores exit code" " + test_config difftool.error.cmd false && + git difftool ${opt} -y -t error branch + " -test_expect_success 'difftool forwards exit code with --trust-exit-code' ' - test_config difftool.error.cmd false && - test_must_fail git difftool -y --trust-exit-code -t error branch -' + test_expect_success "difftool ${opt} forwards exit code with --trust-exit-code" " + test_config difftool.error.cmd false && + test_must_fail git difftool ${opt} -y --trust-exit-code -t error branch + " -test_expect_success 'difftool forwards exit code with --trust-exit-code for built-ins' ' - test_config difftool.vimdiff.path false && - test_must_fail git difftool -y --trust-exit-code -t vimdiff branch -' + test_expect_success "difftool ${opt} forwards exit code with --trust-exit-code for built-ins" " + test_config difftool.vimdiff.path false && + test_must_fail git difftool ${opt} -y --trust-exit-code -t vimdiff branch + " -test_expect_success 'difftool honors difftool.trustExitCode = true' ' - test_config difftool.error.cmd false && - test_config difftool.trustExitCode true && - test_must_fail git difftool -y -t error branch -' + test_expect_success "difftool ${opt} honors difftool.trustExitCode = true" " + test_config difftool.error.cmd false && + test_config difftool.trustExitCode true && + test_must_fail git difftool ${opt} -y -t error branch + " -test_expect_success 'difftool honors difftool.trustExitCode = false' ' - test_config difftool.error.cmd false && - test_config difftool.trustExitCode false && - git difftool -y -t error branch -' + test_expect_success "difftool ${opt} honors difftool.trustExitCode = false" " + test_config difftool.error.cmd false && + test_config difftool.trustExitCode false && + git difftool ${opt} -y -t error branch + " -test_expect_success 'difftool ignores exit code with --no-trust-exit-code' ' - test_config difftool.error.cmd false && - test_config difftool.trustExitCode true && - git difftool -y --no-trust-exit-code -t error branch -' + test_expect_success "difftool ${opt} ignores exit code with --no-trust-exit-code" " + test_config difftool.error.cmd false && + test_config difftool.trustExitCode true && + git difftool ${opt} -y --no-trust-exit-code -t error branch + " -test_expect_success 'difftool stops on error with --trust-exit-code' ' - test_when_finished "rm -f for-diff .git/fail-right-file" && - test_when_finished "git reset -- for-diff" && - write_script .git/fail-right-file <<-\EOF && - echo failed - exit 1 - EOF - >for-diff && - git add for-diff && - test_must_fail git difftool -y --trust-exit-code \ - --extcmd .git/fail-right-file branch >actual && - test_line_count = 1 actual -' + test_expect_success "difftool ${opt} stops on error with --trust-exit-code" " + test_when_finished 'rm -f for-diff .git/fail-right-file' && + test_when_finished 'git reset -- for-diff' && + write_script .git/fail-right-file <<-\EOF && + echo failed + exit 1 + EOF + >for-diff && + git add for-diff && + test_must_fail git difftool ${opt} -y --trust-exit-code \ + --extcmd .git/fail-right-file branch >actual && + test_line_count = 1 actual + " -test_expect_success 'difftool honors exit status if command not found' ' - test_config difftool.nonexistent.cmd i-dont-exist && - test_config difftool.trustExitCode false && - test_must_fail git difftool -y -t nonexistent branch -' + test_expect_success "difftool ${opt} honors exit status if command not found" " + test_config difftool.nonexistent.cmd i-dont-exist && + test_config difftool.trustExitCode false && + if test "${opt}" = '--dir-diff' + then + expected_code=127 + else + expected_code=128 + fi && + test_expect_code \${expected_code} git difftool ${opt} -y -t nonexistent branch + " +done test_expect_success 'difftool honors --gui' ' difftool_test_setup && diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 935df6a1db..0943dfa18a 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -67,6 +67,51 @@ test_expect_success 'maintenance.auto config option' ' test_subcommand ! git maintenance run --auto --quiet <false ' +test_expect_success 'register uses XDG_CONFIG_HOME config if it exists' ' + test_when_finished rm -r .config/git/config && + ( + XDG_CONFIG_HOME=.config && + export XDG_CONFIG_HOME && + mkdir -p $XDG_CONFIG_HOME/git && + >$XDG_CONFIG_HOME/git/config && + git maintenance register && + git config --file=$XDG_CONFIG_HOME/git/config --get maintenance.repo >actual && + pwd >expect && + test_cmp expect actual + ) +' + +test_expect_success 'register does not need XDG_CONFIG_HOME config to exist' ' + test_when_finished git maintenance unregister && + test_path_is_missing $XDG_CONFIG_HOME/git/config && + git maintenance register && + git config --global --get maintenance.repo >actual && + pwd >expect && + test_cmp expect actual +' + +test_expect_success 'unregister uses XDG_CONFIG_HOME config if it exists' ' + test_when_finished rm -r .config/git/config && + ( + XDG_CONFIG_HOME=.config && + export XDG_CONFIG_HOME && + mkdir -p $XDG_CONFIG_HOME/git && + >$XDG_CONFIG_HOME/git/config && + git maintenance register && + git maintenance unregister && + test_must_fail git config --file=$XDG_CONFIG_HOME/git/config --get maintenance.repo >actual && + test_must_be_empty actual + ) +' + +test_expect_success 'unregister does not need XDG_CONFIG_HOME config to exist' ' + test_path_is_missing $XDG_CONFIG_HOME/git/config && + git maintenance register && + git maintenance unregister && + test_must_fail git config --global --get maintenance.repo >actual && + test_must_be_empty actual +' + test_expect_success 'maintenance.<task>.enabled' ' git config maintenance.gc.enabled false && git config maintenance.commit-graph.enabled true && @@ -157,7 +202,8 @@ test_expect_success 'prefetch multiple remotes' ' fetchargs="--prefetch --prune --no-tags --no-write-fetch-head --recurse-submodules=no --quiet" && test_subcommand git fetch remote1 $fetchargs <run-prefetch.txt && test_subcommand git fetch remote2 $fetchargs <run-prefetch.txt && - test_path_is_missing .git/refs/remotes && + git for-each-ref refs/remotes >actual && + test_must_be_empty actual && git log prefetch/remotes/remote1/one && git log prefetch/remotes/remote2/two && git fetch --all && diff --git a/t/t9002-column.sh b/t/t9002-column.sh index 6d3dbde3fe..d5b98e615b 100755 --- a/t/t9002-column.sh +++ b/t/t9002-column.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='git column' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -195,4 +196,15 @@ EOF test_cmp expected actual ' +test_expect_success 'padding must be non-negative' ' + cat >input <<\EOF && +1 2 3 4 5 6 +EOF + cat >expected <<\EOF && +fatal: --padding must be non-negative +EOF + test_must_fail git column --mode=column --padding=-1 <input >actual 2>&1 && + test_cmp expected actual +' + test_done diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh index 32317d6bca..e06538b1c8 100755 --- a/t/t9114-git-svn-dcommit-merge.sh +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -27,7 +27,7 @@ cat << EOF # 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/>. +# along with this program; if not, see <https://www.gnu.org/licenses/>. # EOF } diff --git a/t/t9133-git-svn-nested-git-repo.sh b/t/t9133-git-svn-nested-git-repo.sh index d8d536269c..8ca24670ac 100755 --- a/t/t9133-git-svn-nested-git-repo.sh +++ b/t/t9133-git-svn-nested-git-repo.sh @@ -11,7 +11,7 @@ test_expect_success 'setup repo with a git repo inside it' ' ( cd s && git init && - test -f .git/HEAD && + git symbolic-ref HEAD && > .git/a && echo a > a && svn_cmd add .git a && diff --git a/t/t9146-git-svn-empty-dirs.sh b/t/t9146-git-svn-empty-dirs.sh index 09606f1b3c..926ac81439 100755 --- a/t/t9146-git-svn-empty-dirs.sh +++ b/t/t9146-git-svn-empty-dirs.sh @@ -20,11 +20,7 @@ test_expect_success 'empty directories exist' ' cd cloned && for i in a b c d d/e d/e/f "weird file name" do - if ! test -d "$i" - then - echo >&2 "$i does not exist" && - exit 1 - fi + test_path_is_dir "$i" || exit 1 done ) ' @@ -37,11 +33,7 @@ test_expect_success 'option automkdirs set to false' ' git svn fetch && for i in a b c d d/e d/e/f "weird file name" do - if test -d "$i" - then - echo >&2 "$i exists" && - exit 1 - fi + test_path_is_missing "$i" || exit 1 done ) ' @@ -52,7 +44,7 @@ test_expect_success 'more emptiness' ' test_expect_success 'git svn rebase creates empty directory' ' ( cd cloned && git svn rebase ) && - test -d cloned/"! !" + test_path_is_dir cloned/"! !" ' test_expect_success 'git svn mkdirs recreates empty directories' ' @@ -62,11 +54,7 @@ test_expect_success 'git svn mkdirs recreates empty directories' ' git svn mkdirs && for i in a b c d d/e d/e/f "weird file name" "! !" do - if ! test -d "$i" - then - echo >&2 "$i does not exist" && - exit 1 - fi + test_path_is_dir "$i" || exit 1 done ) ' @@ -78,25 +66,13 @@ test_expect_success 'git svn mkdirs -r works' ' git svn mkdirs -r7 && for i in a b c d d/e d/e/f "weird file name" do - if ! test -d "$i" - then - echo >&2 "$i does not exist" && - exit 1 - fi + test_path_is_dir "$i" || exit 1 done && - if test -d "! !" - then - echo >&2 "$i should not exist" && - exit 1 - fi && + test_path_is_missing "! !" || exit 1 && git svn mkdirs -r8 && - if ! test -d "! !" - then - echo >&2 "$i not exist" && - exit 1 - fi + test_path_is_dir "! !" || exit 1 ) ' @@ -114,11 +90,7 @@ test_expect_success 'empty directories in trunk exist' ' cd trunk && for i in a "weird file name" do - if ! test -d "$i" - then - echo >&2 "$i does not exist" && - exit 1 - fi + test_path_is_dir "$i" || exit 1 done ) ' @@ -129,7 +101,7 @@ test_expect_success 'remove a top-level directory from svn' ' test_expect_success 'removed top-level directory does not exist' ' git svn clone "$svnrepo" removed && - test ! -e removed/d + test_path_is_missing removed/d ' unhandled=.git/svn/refs/remotes/git-svn/unhandled.log @@ -143,15 +115,11 @@ test_expect_success 'git svn gc-ed files work' ' svn_cmd mkdir -m gz "$svnrepo"/gz && git reset --hard $(git rev-list HEAD | tail -1) && git svn rebase && - test -f "$unhandled".gz && - test -f "$unhandled" && + test_path_is_file "$unhandled".gz && + test_path_is_file "$unhandled" && for i in a b c "weird file name" gz "! !" do - if ! test -d "$i" - then - echo >&2 "$i does not exist" && - exit 1 - fi + test_path_is_dir "$i" || exit 1 done fi ) diff --git a/t/t9164-git-svn-dcommit-concurrent.sh b/t/t9164-git-svn-dcommit-concurrent.sh index c8e6c0733f..d1dec89c3b 100755 --- a/t/t9164-git-svn-dcommit-concurrent.sh +++ b/t/t9164-git-svn-dcommit-concurrent.sh @@ -46,6 +46,14 @@ setup_hook() "passed to setup_hook" >&2 ; return 1; } echo "cnt=$skip_revs" > "$hook_type-counter" rm -f "$rawsvnrepo/hooks/"*-commit # drop previous hooks + + # Subversion hooks run with an empty environment by default. We thus + # need to propagate PATH so that we can find executables. + cat >"$rawsvnrepo/conf/hooks-env" <<-EOF + [default] + PATH = ${PATH} + EOF + hook="$rawsvnrepo/hooks/$hook_type" cat > "$hook" <<- 'EOF1' #!/bin/sh @@ -63,7 +71,6 @@ EOF1 if [ "$hook_type" = "pre-commit" ]; then echo "echo 'commit disallowed' >&2; exit 1" >>"$hook" else - echo "PATH=\"$PATH\"; export PATH" >>"$hook" echo "svnconf=\"$svnconf\"" >>"$hook" cat >>"$hook" <<- 'EOF2' cd work-auto-commits.svn diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh index 4432a30d10..428339e342 100755 --- a/t/t9210-scalar.sh +++ b/t/t9210-scalar.sh @@ -154,7 +154,14 @@ test_expect_success 'scalar clone' ' test_cmp expect actual && test_path_is_missing 1/2 && - test_must_fail git rev-list --missing=print $second && + + # This relies on the fact that the presence of "--missing" + # on the command line forces lazy fetching off before + # "$second^{blob}" gets parsed. Without "^{blob}", a + # bare object name "$second" is taken into the queue and + # the command may not fail with a fixed "rev-list --missing". + test_must_fail git rev-list --missing=print "$second^{blob}" -- && + git rev-list $second && git cat-file blob $second >actual && echo "second" >expect && diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 26c25c0eb2..e9a12c18bb 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -791,4 +791,14 @@ test_expect_success 'fast-export --first-parent outputs all revisions output by ) ' +test_expect_success 'fast-export handles --end-of-options' ' + git update-ref refs/heads/nodash HEAD && + git update-ref refs/heads/--dashes HEAD && + git fast-export --end-of-options nodash >expect && + git fast-export --end-of-options --dashes >actual.raw && + # fix up lines which mention the ref for comparison + sed s/--dashes/nodash/ <actual.raw >actual && + test_cmp expect actual +' + test_done diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 0333065d4d..7679780fb8 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -627,6 +627,7 @@ test_expect_success \ test_expect_success 'setup' ' version=$(git config core.repositoryformatversion) && algo=$(test_might_fail git config extensions.objectformat) && + refstorage=$(test_might_fail git config extensions.refstorage) && cat >.git/config <<-\EOF && # testing noval and alternate separator [gitweb] @@ -637,6 +638,10 @@ test_expect_success 'setup' ' if test -n "$algo" then git config extensions.objectformat "$algo" + fi && + if test -n "$refstorage" + then + git config extensions.refstorage "$refstorage" fi ' diff --git a/t/t9700/test.pl b/t/t9700/test.pl index 6d753708d2..d8e85482ab 100755 --- a/t/t9700/test.pl +++ b/t/t9700/test.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl use lib (split(/:/, $ENV{GITPERLLIB})); -use 5.008; +use 5.008001; use warnings; use strict; diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh index 73cca0d143..c598011635 100755 --- a/t/t9801-git-p4-branch.sh +++ b/t/t9801-git-p4-branch.sh @@ -466,7 +466,7 @@ test_expect_success 'git p4 clone complex branches with excluded files' ' ) ' -# From a report in http://stackoverflow.com/questions/11893688 +# From a report in https://stackoverflow.com/questions/11893688 # where --use-client-spec caused branch prefixes not to be removed; # every file in git appeared into a subdirectory of the branch name. test_expect_success 'use-client-spec detect-branches setup' ' diff --git a/t/t9816-git-p4-locked.sh b/t/t9816-git-p4-locked.sh index 932841003c..5e904ac80d 100755 --- a/t/t9816-git-p4-locked.sh +++ b/t/t9816-git-p4-locked.sh @@ -9,7 +9,7 @@ test_expect_success 'start p4d' ' ' # See -# http://www.perforce.com/perforce/doc.current/manuals/p4sag/03_superuser.html#1088563 +# https://web.archive.org/web/20150602090517/http://www.perforce.com/perforce/doc.current/manuals/p4sag/chapter.superuser.html#superuser.basic.typemap_locking # for suggestions on how to configure "sitewide pessimistic locking" # where only one person can have a file open for edit at a time. test_expect_success 'init depot' ' diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index a7c3b4eb63..b16c284181 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -5,6 +5,17 @@ test_description='test bash completion' +# The Bash completion scripts must not print anything to either stdout or +# stderr, which we try to verify. When tracing is enabled without support for +# BASH_XTRACEFD this assertion will fail, so we have to mark the test as +# untraceable with such ancient Bash versions. +test_untraceable=UnfortunatelyYes + +# Override environment and always use master for the default initial branch +# name for these tests, so that rev completion candidates are as expected. +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + . ./lib-bash.sh complete () @@ -87,9 +98,11 @@ test_completion () else sed -e 's/Z$//' |sort >expected fi && - run_completion "$1" && + run_completion "$1" >"$TRASH_DIRECTORY"/bash-completion-output 2>&1 && sort out >out_sorted && - test_cmp expected out_sorted + test_cmp expected out_sorted && + test_must_be_empty "$TRASH_DIRECTORY"/bash-completion-output && + rm "$TRASH_DIRECTORY"/bash-completion-output } # Test __gitcomp. @@ -1259,6 +1272,142 @@ test_expect_success 'git switch - with no options, complete local branches and u EOF ' +test_expect_success 'git bisect - when not bisecting, complete only replay and start subcommands' ' + test_completion "git bisect " <<-\EOF + replay Z + start Z + EOF +' + +test_expect_success 'git bisect - complete options to start subcommand' ' + test_completion "git bisect start --" <<-\EOF + --term-new Z + --term-bad Z + --term-old Z + --term-good Z + --no-checkout Z + --first-parent Z + EOF +' + +test_expect_success 'setup for git-bisect tests requiring a repo' ' + git init git-bisect && + ( + cd git-bisect && + echo "initial contents" >file && + git add file && + git commit -am "Initial commit" && + git tag initial && + echo "new line" >>file && + git commit -am "First change" && + echo "another new line" >>file && + git commit -am "Second change" && + git tag final + ) +' + +test_expect_success 'git bisect - start subcommand arguments before double-dash are completed as revs' ' + ( + cd git-bisect && + test_completion "git bisect start " <<-\EOF + HEAD Z + final Z + initial Z + master Z + EOF + ) +' + +# Note that these arguments are <pathspec>s, which in practice the fallback +# completion (not the git completion) later ends up completing as paths. +test_expect_success 'git bisect - start subcommand arguments after double-dash are not completed' ' + ( + cd git-bisect && + test_completion "git bisect start final initial -- " "" + ) +' + +test_expect_success 'setup for git-bisect tests requiring ongoing bisection' ' + ( + cd git-bisect && + git bisect start --term-new=custom_new --term-old=custom_old final initial + ) +' + +test_expect_success 'git-bisect - when bisecting all subcommands are candidates' ' + ( + cd git-bisect && + test_completion "git bisect " <<-\EOF + start Z + bad Z + custom_new Z + custom_old Z + new Z + good Z + old Z + terms Z + skip Z + reset Z + visualize Z + replay Z + log Z + run Z + help Z + EOF + ) +' + +test_expect_success 'git-bisect - options to terms subcommand are candidates' ' + ( + cd git-bisect && + test_completion "git bisect terms --" <<-\EOF + --term-bad Z + --term-good Z + --term-new Z + --term-old Z + EOF + ) +' + +test_expect_success 'git-bisect - git-log options to visualize subcommand are candidates' ' + ( + cd git-bisect && + # The completion used for git-log and here does not complete + # every git-log option, so rather than hope to stay in sync + # with exactly what it does we will just spot-test here. + test_completion "git bisect visualize --sta" <<-\EOF && + --stat Z + EOF + test_completion "git bisect visualize --summar" <<-\EOF + --summary Z + EOF + ) +' + +test_expect_success 'git-bisect - view subcommand is not a candidate' ' + ( + cd git-bisect && + test_completion "git bisect vi" <<-\EOF + visualize Z + EOF + ) +' + +test_expect_success 'git-bisect - existing view subcommand is recognized and enables completion of git-log options' ' + ( + cd git-bisect && + # The completion used for git-log and here does not complete + # every git-log option, so rather than hope to stay in sync + # with exactly what it does we will just spot-test here. + test_completion "git bisect view --sta" <<-\EOF && + --stat Z + EOF + test_completion "git bisect view --summar" <<-\EOF + --summary Z + EOF + ) +' + test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' ' test_completion "git checkout " <<-\EOF HEAD Z @@ -1571,7 +1720,7 @@ test_expect_success FUNNYNAMES,!CYGWIN 'cone mode sparse-checkout completes dire ) ' -test_expect_success 'non-cone mode sparse-checkout uses bash completion' ' +test_expect_success 'non-cone mode sparse-checkout gives rooted paths' ' # reset sparse-checkout repo to non-cone mode git -C sparse-checkout sparse-checkout disable && git -C sparse-checkout sparse-checkout set --no-cone && @@ -1581,7 +1730,12 @@ test_expect_success 'non-cone mode sparse-checkout uses bash completion' ' # expected to be empty since we have not configured # custom completion for non-cone mode test_completion "git sparse-checkout set f" <<-\EOF - + /folder1/0/1/t.txt Z + /folder1/expected Z + /folder1/out Z + /folder1/out_sorted Z + /folder2/0/t.txt Z + /folder3/t.txt Z EOF ) ' @@ -1920,6 +2074,14 @@ test_expect_success 'git checkout - --orphan with branch already provided comple EOF ' +test_expect_success 'git restore completes modified files' ' + test_commit A a.file && + echo B >a.file && + test_completion "git restore a." <<-\EOF + a.file + EOF +' + test_expect_success 'teardown after ref completion' ' git branch -d matching-branch && git tag -d matching-tag && @@ -2562,6 +2724,35 @@ test_expect_success 'git config - variable name include' ' EOF ' +test_expect_success 'setup for git config submodule tests' ' + test_create_repo sub && + test_commit -C sub initial && + git submodule add ./sub +' + +test_expect_success 'git config - variable name - submodule and __git_compute_first_level_config_vars_for_section' ' + test_completion "git config submodule." <<-\EOF + submodule.active Z + submodule.alternateErrorStrategy Z + submodule.alternateLocation Z + submodule.fetchJobs Z + submodule.propagateBranches Z + submodule.recurse Z + submodule.sub.Z + EOF +' + +test_expect_success 'git config - variable name - __git_compute_second_level_config_vars_for_section' ' + test_completion "git config submodule.sub." <<-\EOF + submodule.sub.url Z + submodule.sub.update Z + submodule.sub.branch Z + submodule.sub.fetchRecurseSubmodules Z + submodule.sub.ignore Z + submodule.sub.active Z + EOF +' + test_expect_success 'git config - value' ' test_completion "git config color.pager " <<-\EOF false Z @@ -2715,4 +2906,31 @@ test_expect_success '__git_complete' ' test_must_fail __git_complete ga missing ' +test_expect_success '__git_pseudoref_exists' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + sane_unset __git_repo_path && + + # HEAD should exist, even if it points to an unborn branch. + __git_pseudoref_exists HEAD >output 2>&1 && + test_must_be_empty output && + + # HEAD points to an existing branch, so it should exist. + test_commit A && + __git_pseudoref_exists HEAD >output 2>&1 && + test_must_be_empty output && + + # CHERRY_PICK_HEAD does not exist, so the existence check should fail. + ! __git_pseudoref_exists CHERRY_PICK_HEAD >output 2>&1 && + test_must_be_empty output && + + # CHERRY_PICK_HEAD points to a commit, so it should exist. + git update-ref CHERRY_PICK_HEAD A && + __git_pseudoref_exists CHERRY_PICK_HEAD >output 2>&1 && + test_must_be_empty output + ) +' + test_done diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 9c3cf12b26..b5eaf7fdc1 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -14,7 +14,7 @@ # 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/ . +# along with this program. If not, see https://www.gnu.org/licenses/ . # The semantics of the editor variables are that of invoking # sh -c "$EDITOR \"$@\"" files ... @@ -1277,7 +1277,7 @@ test_grep () { if test $# -lt 2 || { test "x!" = "x$1" && test $# -lt 3 ; } then - BUG "too few parameters to test_i18ngrep" + BUG "too few parameters to test_grep" fi if test "x!" = "x$1" @@ -1659,6 +1659,11 @@ test_detect_hash () { test_hash_algo="${GIT_TEST_DEFAULT_HASH:-sha1}" } +# Detect the hash algorithm in use. +test_detect_ref_format () { + echo "${GIT_TEST_DEFAULT_REF_FORMAT:-files}" +} + # Load common hash metadata and common placeholder object IDs for use with # test_oid. test_oid_init () { @@ -1874,6 +1879,20 @@ test_region () { return 0 } +# Check that the given data fragment was included as part of the +# trace2-format trace on stdin. +# +# test_trace2_data <category> <key> <value> +# +# For example, to look for trace2_data_intmax("pack-objects", repo, +# "reused", N) in an invocation of "git pack-objects", run: +# +# GIT_TRACE2_EVENT="$(pwd)/trace.txt" git pack-objects ... && +# test_trace2_data pack-objects reused N <trace2.txt +test_trace2_data () { + grep -e '"category":"'"$1"'","key":"'"$2"'","value":"'"$3"'"' +} + # Given a GIT_TRACE2_EVENT log over stdin, writes to stdout a list of URLs # sent to git-remote-https child processes. test_remote_https_urls() { diff --git a/t/test-lib-github-workflow-markup.sh b/t/test-lib-github-workflow-markup.sh index 9c5339c577..33405c90d7 100644 --- a/t/test-lib-github-workflow-markup.sh +++ b/t/test-lib-github-workflow-markup.sh @@ -14,7 +14,7 @@ # 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/ . +# along with this program. If not, see https://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 @@ -42,8 +42,8 @@ finalize_test_case_output () { fixed) echo >>$github_markup_output "::notice::fixed: $this_test.$test_count $1" ;; - ok) - # Exit without printing the "ok" tests + ok|broken) + # Exit without printing the "ok" or ""broken" tests return ;; esac diff --git a/t/test-lib-junit.sh b/t/test-lib-junit.sh index 79c31c788b..76cbbd3299 100644 --- a/t/test-lib-junit.sh +++ b/t/test-lib-junit.sh @@ -15,7 +15,7 @@ # 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/ . +# along with this program. If not, see https://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 diff --git a/t/test-lib.sh b/t/test-lib.sh index 1656c9eed0..c8af8dab79 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -13,7 +13,7 @@ # 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/ . +# along with this program. If not, see https://www.gnu.org/licenses/ . # Test the binaries we have just built. The tests are kept in # t/ subdirectory and are run in 'trash directory' subdirectory. @@ -542,6 +542,8 @@ export EDITOR GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-sha1}" export GIT_DEFAULT_HASH +GIT_DEFAULT_REF_FORMAT="${GIT_TEST_DEFAULT_REF_FORMAT:-files}" +export GIT_DEFAULT_REF_FORMAT GIT_TEST_MERGE_ALGORITHM="${GIT_TEST_MERGE_ALGORITHM:-ort}" export GIT_TEST_MERGE_ALGORITHM @@ -1295,6 +1297,11 @@ test_done () { EOF fi + if test -z "$passes_sanitize_leak" && test_bool_env TEST_PASSES_SANITIZE_LEAK false + then + BAIL_OUT "Please, set TEST_PASSES_SANITIZE_LEAK before sourcing test-lib.sh" + fi + if test "$test_fixed" != 0 then say_color error "# $test_fixed known breakage(s) vanished; please update test(s)" @@ -1745,7 +1752,16 @@ parisc* | hppa*) ;; esac -test_set_prereq REFFILES +case "$GIT_DEFAULT_REF_FORMAT" in +files) + test_set_prereq REFFILES;; +reftable) + test_set_prereq REFTABLE;; +*) + echo 2>&1 "error: unknown ref format $GIT_DEFAULT_REF_FORMAT" + exit 1 + ;; +esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_CURL" && test_set_prereq LIBCURL @@ -1936,6 +1952,10 @@ test_lazy_prereq SHA1 ' esac ' +test_lazy_prereq DEFAULT_REPO_FORMAT ' + test_have_prereq SHA1,REFFILES +' + # Ensure that no test accidentally triggers a Git command # that runs the actual maintenance scheduler, affecting a user's # system permanently. diff --git a/t/test-terminal.perl b/t/test-terminal.perl index 1bcf01a9a4..3810e9bb43 100755 --- a/t/test-terminal.perl +++ b/t/test-terminal.perl @@ -1,5 +1,5 @@ #!/usr/bin/perl -use 5.008; +use 5.008001; use strict; use warnings; use IO::Pty; diff --git a/t/unit-tests/.gitignore b/t/unit-tests/.gitignore new file mode 100644 index 0000000000..5e56e040ec --- /dev/null +++ b/t/unit-tests/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/t/unit-tests/t-basic.c b/t/unit-tests/t-basic.c new file mode 100644 index 0000000000..fda1ae59a6 --- /dev/null +++ b/t/unit-tests/t-basic.c @@ -0,0 +1,95 @@ +#include "test-lib.h" + +/* + * The purpose of this "unit test" is to verify a few invariants of the unit + * test framework itself, as well as to provide examples of output from actually + * failing tests. As such, it is intended that this test fails, and thus it + * should not be run as part of `make unit-tests`. Instead, we verify it behaves + * as expected in the integration test t0080-unit-test-output.sh + */ + +/* Used to store the return value of check_int(). */ +static int check_res; + +/* Used to store the return value of TEST(). */ +static int test_res; + +static void t_res(int expect) +{ + check_int(check_res, ==, expect); + check_int(test_res, ==, expect); +} + +static void t_todo(int x) +{ + check_res = TEST_TODO(check(x)); +} + +static void t_skip(void) +{ + check(0); + test_skip("missing prerequisite"); + check(1); +} + +static int do_skip(void) +{ + test_skip("missing prerequisite"); + return 1; +} + +static void t_skip_todo(void) +{ + check_res = TEST_TODO(do_skip()); +} + +static void t_todo_after_fail(void) +{ + check(0); + TEST_TODO(check(0)); +} + +static void t_fail_after_todo(void) +{ + check(1); + TEST_TODO(check(0)); + check(0); +} + +static void t_messages(void) +{ + check_str("\thello\\", "there\"\n"); + check_str("NULL", NULL); + check_char('a', ==, '\n'); + check_char('\\', ==, '\''); +} + +static void t_empty(void) +{ + ; /* empty */ +} + +int cmd_main(int argc, const char **argv) +{ + test_res = TEST(check_res = check_int(1, ==, 1), "passing test"); + TEST(t_res(1), "passing test and assertion return 1"); + test_res = TEST(check_res = check_int(1, ==, 2), "failing test"); + TEST(t_res(0), "failing test and assertion return 0"); + test_res = TEST(t_todo(0), "passing TEST_TODO()"); + TEST(t_res(1), "passing TEST_TODO() returns 1"); + test_res = TEST(t_todo(1), "failing TEST_TODO()"); + TEST(t_res(0), "failing TEST_TODO() returns 0"); + test_res = TEST(t_skip(), "test_skip()"); + TEST(check_int(test_res, ==, 1), "skipped test returns 1"); + test_res = TEST(t_skip_todo(), "test_skip() inside TEST_TODO()"); + TEST(t_res(1), "test_skip() inside TEST_TODO() returns 1"); + test_res = TEST(t_todo_after_fail(), "TEST_TODO() after failing check"); + TEST(check_int(test_res, ==, 0), "TEST_TODO() after failing check returns 0"); + test_res = TEST(t_fail_after_todo(), "failing check after TEST_TODO()"); + TEST(check_int(test_res, ==, 0), "failing check after TEST_TODO() returns 0"); + TEST(t_messages(), "messages from failing string and char comparison"); + test_res = TEST(t_empty(), "test with no checks"); + TEST(check_int(test_res, ==, 0), "test with no checks returns 0"); + + return test_done(); +} diff --git a/t/unit-tests/t-ctype.c b/t/unit-tests/t-ctype.c new file mode 100644 index 0000000000..f315489984 --- /dev/null +++ b/t/unit-tests/t-ctype.c @@ -0,0 +1,80 @@ +#include "test-lib.h" + +static int is_in(const char *s, int ch) +{ + /* + * We can't find NUL using strchr. Accept it as the first + * character in the spec -- there are no empty classes. + */ + if (ch == '\0') + return ch == *s; + if (*s == '\0') + s++; + return !!strchr(s, ch); +} + +/* Macro to test a character type */ +#define TEST_CTYPE_FUNC(func, string) \ +static void test_ctype_##func(void) { \ + for (int i = 0; i < 256; i++) { \ + if (!check_int(func(i), ==, is_in(string, i))) \ + test_msg(" i: 0x%02x", i); \ + } \ + if (!check(!func(EOF))) \ + test_msg(" i: 0x%02x (EOF)", EOF); \ +} + +#define TEST_CHAR_CLASS(class) TEST(test_ctype_##class(), #class " works") + +#define DIGIT "0123456789" +#define LOWER "abcdefghijklmnopqrstuvwxyz" +#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define PUNCT "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" +#define ASCII \ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" \ + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" +#define CNTRL \ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ + "\x7f" + +TEST_CTYPE_FUNC(isdigit, DIGIT) +TEST_CTYPE_FUNC(isspace, " \n\r\t") +TEST_CTYPE_FUNC(isalpha, LOWER UPPER) +TEST_CTYPE_FUNC(isalnum, LOWER UPPER DIGIT) +TEST_CTYPE_FUNC(is_glob_special, "*?[\\") +TEST_CTYPE_FUNC(is_regex_special, "$()*+.?[\\^{|") +TEST_CTYPE_FUNC(is_pathspec_magic, "!\"#%&',-/:;<=>@_`~") +TEST_CTYPE_FUNC(isascii, ASCII) +TEST_CTYPE_FUNC(islower, LOWER) +TEST_CTYPE_FUNC(isupper, UPPER) +TEST_CTYPE_FUNC(iscntrl, CNTRL) +TEST_CTYPE_FUNC(ispunct, PUNCT) +TEST_CTYPE_FUNC(isxdigit, DIGIT "abcdefABCDEF") +TEST_CTYPE_FUNC(isprint, LOWER UPPER DIGIT PUNCT " ") + +int cmd_main(int argc, const char **argv) { + /* Run all character type tests */ + TEST_CHAR_CLASS(isspace); + TEST_CHAR_CLASS(isdigit); + TEST_CHAR_CLASS(isalpha); + TEST_CHAR_CLASS(isalnum); + TEST_CHAR_CLASS(is_glob_special); + TEST_CHAR_CLASS(is_regex_special); + TEST_CHAR_CLASS(is_pathspec_magic); + TEST_CHAR_CLASS(isascii); + TEST_CHAR_CLASS(islower); + TEST_CHAR_CLASS(isupper); + TEST_CHAR_CLASS(iscntrl); + TEST_CHAR_CLASS(ispunct); + TEST_CHAR_CLASS(isxdigit); + TEST_CHAR_CLASS(isprint); + + return test_done(); +} diff --git a/t/unit-tests/t-mem-pool.c b/t/unit-tests/t-mem-pool.c new file mode 100644 index 0000000000..a0d57df761 --- /dev/null +++ b/t/unit-tests/t-mem-pool.c @@ -0,0 +1,31 @@ +#include "test-lib.h" +#include "mem-pool.h" + +static void setup_static(void (*f)(struct mem_pool *), size_t block_alloc) +{ + struct mem_pool pool = { .block_alloc = block_alloc }; + f(&pool); + mem_pool_discard(&pool, 0); +} + +static void t_calloc_100(struct mem_pool *pool) +{ + size_t size = 100; + char *buffer = mem_pool_calloc(pool, 1, size); + for (size_t i = 0; i < size; i++) + check_int(buffer[i], ==, 0); + if (!check(pool->mp_block != NULL)) + return; + check(pool->mp_block->next_free != NULL); + check(pool->mp_block->end != NULL); +} + +int cmd_main(int argc, const char **argv) +{ + TEST(setup_static(t_calloc_100, 1024 * 1024), + "mem_pool_calloc returns 100 zeroed bytes with big block"); + TEST(setup_static(t_calloc_100, 1), + "mem_pool_calloc returns 100 zeroed bytes with tiny block"); + + return test_done(); +} diff --git a/t/unit-tests/t-prio-queue.c b/t/unit-tests/t-prio-queue.c new file mode 100644 index 0000000000..d78b002f9e --- /dev/null +++ b/t/unit-tests/t-prio-queue.c @@ -0,0 +1,98 @@ +#include "test-lib.h" +#include "prio-queue.h" + +static int intcmp(const void *va, const void *vb, void *data UNUSED) +{ + const int *a = va, *b = vb; + return *a - *b; +} + + +#define MISSING -1 +#define DUMP -2 +#define STACK -3 +#define GET -4 +#define REVERSE -5 + +static int show(int *v) +{ + return v ? *v : MISSING; +} + +static void test_prio_queue(int *input, int *result, size_t input_size) +{ + struct prio_queue pq = { intcmp }; + + for (int i = 0, j = 0; i < input_size; i++) { + void *peek, *get; + switch(input[i]) { + case GET: + peek = prio_queue_peek(&pq); + get = prio_queue_get(&pq); + if (!check(peek == get)) + return; + if(!check_int(result[j++], ==, show(get))) + test_msg("failed at result[] index %d", j-1); + break; + case DUMP: + while ((peek = prio_queue_peek(&pq))) { + get = prio_queue_get(&pq); + if (!check(peek == get)) + return; + if(!check_int(result[j++], ==, show(get))) + test_msg("failed at result[] index %d", j-1); + } + break; + case STACK: + pq.compare = NULL; + break; + case REVERSE: + prio_queue_reverse(&pq); + break; + default: + prio_queue_put(&pq, &input[i]); + break; + } + } + clear_prio_queue(&pq); +} + +#define BASIC_INPUT 2, 6, 3, 10, 9, 5, 7, 4, 5, 8, 1, DUMP +#define BASIC_RESULT 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10 + +#define MIXED_PUT_GET_INPUT 6, 2, 4, GET, 5, 3, GET, GET, 1, DUMP +#define MIXED_PUT_GET_RESULT 2, 3, 4, 1, 5, 6 + +#define EMPTY_QUEUE_INPUT 1, 2, GET, GET, GET, 1, 2, GET, GET, GET +#define EMPTY_QUEUE_RESULT 1, 2, MISSING, 1, 2, MISSING + +#define STACK_INPUT STACK, 8, 1, 5, 4, 6, 2, 3, DUMP +#define STACK_RESULT 3, 2, 6, 4, 5, 1, 8 + +#define REVERSE_STACK_INPUT STACK, 1, 2, 3, 4, 5, 6, REVERSE, DUMP +#define REVERSE_STACK_RESULT 1, 2, 3, 4, 5, 6 + +#define TEST_INPUT(INPUT, RESULT, name) \ + static void test_##name(void) \ +{ \ + int input[] = {INPUT}; \ + int result[] = {RESULT}; \ + test_prio_queue(input, result, ARRAY_SIZE(input)); \ +} + +TEST_INPUT(BASIC_INPUT, BASIC_RESULT, basic) +TEST_INPUT(MIXED_PUT_GET_INPUT, MIXED_PUT_GET_RESULT, mixed) +TEST_INPUT(EMPTY_QUEUE_INPUT, EMPTY_QUEUE_RESULT, empty) +TEST_INPUT(STACK_INPUT, STACK_RESULT, stack) +TEST_INPUT(REVERSE_STACK_INPUT, REVERSE_STACK_RESULT, reverse) + +int cmd_main(int argc, const char **argv) +{ + TEST(test_basic(), "prio-queue works for basic input"); + TEST(test_mixed(), "prio-queue works for mixed put & get commands"); + TEST(test_empty(), "prio-queue works when queue is empty"); + TEST(test_stack(), "prio-queue works when used as a LIFO stack"); + TEST(test_reverse(), "prio-queue works when LIFO stack is reversed"); + + return test_done(); +} diff --git a/t/unit-tests/t-strbuf.c b/t/unit-tests/t-strbuf.c new file mode 100644 index 0000000000..de434a4441 --- /dev/null +++ b/t/unit-tests/t-strbuf.c @@ -0,0 +1,120 @@ +#include "test-lib.h" +#include "strbuf.h" + +/* wrapper that supplies tests with an empty, initialized strbuf */ +static void setup(void (*f)(struct strbuf*, void*), void *data) +{ + struct strbuf buf = STRBUF_INIT; + + f(&buf, data); + strbuf_release(&buf); + check_uint(buf.len, ==, 0); + check_uint(buf.alloc, ==, 0); +} + +/* wrapper that supplies tests with a populated, initialized strbuf */ +static void setup_populated(void (*f)(struct strbuf*, void*), char *init_str, void *data) +{ + struct strbuf buf = STRBUF_INIT; + + strbuf_addstr(&buf, init_str); + check_uint(buf.len, ==, strlen(init_str)); + f(&buf, data); + strbuf_release(&buf); + check_uint(buf.len, ==, 0); + check_uint(buf.alloc, ==, 0); +} + +static int assert_sane_strbuf(struct strbuf *buf) +{ + /* Initialized strbufs should always have a non-NULL buffer */ + if (!check(!!buf->buf)) + return 0; + /* Buffers should always be NUL-terminated */ + if (!check_char(buf->buf[buf->len], ==, '\0')) + return 0; + /* + * Freshly-initialized strbufs may not have a dynamically allocated + * buffer + */ + if (buf->len == 0 && buf->alloc == 0) + return 1; + /* alloc must be at least one byte larger than len */ + return check_uint(buf->len, <, buf->alloc); +} + +static void t_static_init(void) +{ + struct strbuf buf = STRBUF_INIT; + + check_uint(buf.len, ==, 0); + check_uint(buf.alloc, ==, 0); + check_char(buf.buf[0], ==, '\0'); +} + +static void t_dynamic_init(void) +{ + struct strbuf buf; + + strbuf_init(&buf, 1024); + check(assert_sane_strbuf(&buf)); + check_uint(buf.len, ==, 0); + check_uint(buf.alloc, >=, 1024); + check_char(buf.buf[0], ==, '\0'); + strbuf_release(&buf); +} + +static void t_addch(struct strbuf *buf, void *data) +{ + const char *p_ch = data; + const char ch = *p_ch; + size_t orig_alloc = buf->alloc; + size_t orig_len = buf->len; + + if (!check(assert_sane_strbuf(buf))) + return; + strbuf_addch(buf, ch); + if (!check(assert_sane_strbuf(buf))) + return; + if (!(check_uint(buf->len, ==, orig_len + 1) && + check_uint(buf->alloc, >=, orig_alloc))) + return; /* avoid de-referencing buf->buf */ + check_char(buf->buf[buf->len - 1], ==, ch); + check_char(buf->buf[buf->len], ==, '\0'); +} + +static void t_addstr(struct strbuf *buf, void *data) +{ + const char *text = data; + size_t len = strlen(text); + size_t orig_alloc = buf->alloc; + size_t orig_len = buf->len; + + if (!check(assert_sane_strbuf(buf))) + return; + strbuf_addstr(buf, text); + if (!check(assert_sane_strbuf(buf))) + return; + if (!(check_uint(buf->len, ==, orig_len + len) && + check_uint(buf->alloc, >=, orig_alloc) && + check_uint(buf->alloc, >, orig_len + len) && + check_char(buf->buf[orig_len + len], ==, '\0'))) + return; + check_str(buf->buf + orig_len, text); +} + +int cmd_main(int argc, const char **argv) +{ + if (!TEST(t_static_init(), "static initialization works")) + test_skip_all("STRBUF_INIT is broken"); + TEST(t_dynamic_init(), "dynamic initialization works"); + TEST(setup(t_addch, "a"), "strbuf_addch adds char"); + TEST(setup(t_addch, ""), "strbuf_addch adds NUL char"); + TEST(setup_populated(t_addch, "initial value", "a"), + "strbuf_addch appends to initial value"); + TEST(setup(t_addstr, "hello there"), "strbuf_addstr adds string"); + TEST(setup_populated(t_addstr, "initial value", "hello there"), + "strbuf_addstr appends string to initial value"); + + return test_done(); +} diff --git a/t/unit-tests/test-lib.c b/t/unit-tests/test-lib.c new file mode 100644 index 0000000000..66d6980ffb --- /dev/null +++ b/t/unit-tests/test-lib.c @@ -0,0 +1,407 @@ +#include "test-lib.h" + +enum result { + RESULT_NONE, + RESULT_FAILURE, + RESULT_SKIP, + RESULT_SUCCESS, + RESULT_TODO +}; + +static struct { + enum result result; + int count; + unsigned failed :1; + unsigned lazy_plan :1; + unsigned running :1; + unsigned skip_all :1; + unsigned todo :1; +} ctx = { + .lazy_plan = 1, + .result = RESULT_NONE, +}; + +/* + * Visual C interpolates the absolute Windows path for `__FILE__`, + * but we want to see relative paths, as verified by t0080. + * There are other compilers that do the same, and are not for + * Windows. + */ +#include "dir.h" + +static const char *make_relative(const char *location) +{ + static char prefix[] = __FILE__, buf[PATH_MAX], *p; + static size_t prefix_len; + static int need_bs_to_fs = -1; + + /* one-time preparation */ + if (need_bs_to_fs < 0) { + size_t len = strlen(prefix); + char needle[] = "t\\unit-tests\\test-lib.c"; + size_t needle_len = strlen(needle); + + if (len < needle_len) + die("unexpected prefix '%s'", prefix); + + /* + * The path could be relative (t/unit-tests/test-lib.c) + * or full (/home/user/git/t/unit-tests/test-lib.c). + * Check the slash between "t" and "unit-tests". + */ + prefix_len = len - needle_len; + if (prefix[prefix_len + 1] == '/') { + /* Oh, we're not Windows */ + for (size_t i = 0; i < needle_len; i++) + if (needle[i] == '\\') + needle[i] = '/'; + need_bs_to_fs = 0; + } else { + need_bs_to_fs = 1; + } + + /* + * prefix_len == 0 if the compiler gives paths relative + * to the root of the working tree. Otherwise, we want + * to see that we did find the needle[] at a directory + * boundary. Again we rely on that needle[] begins with + * "t" followed by the directory separator. + */ + if (fspathcmp(needle, prefix + prefix_len) || + (prefix_len && prefix[prefix_len - 1] != needle[1])) + die("unexpected suffix of '%s'", prefix); + } + + /* + * Does it not start with the expected prefix? + * Return it as-is without making it worse. + */ + if (prefix_len && fspathncmp(location, prefix, prefix_len)) + return location; + + /* + * If we do not need to munge directory separator, we can return + * the substring at the tail of the location. + */ + if (!need_bs_to_fs) + return location + prefix_len; + + /* convert backslashes to forward slashes */ + strlcpy(buf, location + prefix_len, sizeof(buf)); + for (p = buf; *p; p++) + if (*p == '\\') + *p = '/'; + return buf; +} + +static void msg_with_prefix(const char *prefix, const char *format, va_list ap) +{ + fflush(stderr); + if (prefix) + fprintf(stdout, "%s", prefix); + vprintf(format, ap); /* TODO: handle newlines */ + putc('\n', stdout); + fflush(stdout); +} + +void test_msg(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + msg_with_prefix("# ", format, ap); + va_end(ap); +} + +void test_plan(int count) +{ + assert(!ctx.running); + + fflush(stderr); + printf("1..%d\n", count); + fflush(stdout); + ctx.lazy_plan = 0; +} + +int test_done(void) +{ + assert(!ctx.running); + + if (ctx.lazy_plan) + test_plan(ctx.count); + + return ctx.failed; +} + +void test_skip(const char *format, ...) +{ + va_list ap; + + assert(ctx.running); + + ctx.result = RESULT_SKIP; + va_start(ap, format); + if (format) + msg_with_prefix("# skipping test - ", format, ap); + va_end(ap); +} + +void test_skip_all(const char *format, ...) +{ + va_list ap; + const char *prefix; + + if (!ctx.count && ctx.lazy_plan) { + /* We have not printed a test plan yet */ + prefix = "1..0 # SKIP "; + ctx.lazy_plan = 0; + } else { + /* We have already printed a test plan */ + prefix = "Bail out! # "; + ctx.failed = 1; + } + ctx.skip_all = 1; + ctx.result = RESULT_SKIP; + va_start(ap, format); + msg_with_prefix(prefix, format, ap); + va_end(ap); +} + +int test__run_begin(void) +{ + assert(!ctx.running); + + ctx.count++; + ctx.result = RESULT_NONE; + ctx.running = 1; + + return ctx.skip_all; +} + +static void print_description(const char *format, va_list ap) +{ + if (format) { + fputs(" - ", stdout); + vprintf(format, ap); + } +} + +int test__run_end(int was_run UNUSED, const char *location, const char *format, ...) +{ + va_list ap; + + assert(ctx.running); + assert(!ctx.todo); + + fflush(stderr); + va_start(ap, format); + if (!ctx.skip_all) { + switch (ctx.result) { + case RESULT_SUCCESS: + printf("ok %d", ctx.count); + print_description(format, ap); + break; + + case RESULT_FAILURE: + printf("not ok %d", ctx.count); + print_description(format, ap); + break; + + case RESULT_TODO: + printf("not ok %d", ctx.count); + print_description(format, ap); + printf(" # TODO"); + break; + + case RESULT_SKIP: + printf("ok %d", ctx.count); + print_description(format, ap); + printf(" # SKIP"); + break; + + case RESULT_NONE: + test_msg("BUG: test has no checks at %s", + make_relative(location)); + printf("not ok %d", ctx.count); + print_description(format, ap); + ctx.result = RESULT_FAILURE; + break; + } + } + va_end(ap); + ctx.running = 0; + if (ctx.skip_all) + return 1; + putc('\n', stdout); + fflush(stdout); + ctx.failed |= ctx.result == RESULT_FAILURE; + + return ctx.result != RESULT_FAILURE; +} + +static void test_fail(void) +{ + assert(ctx.result != RESULT_SKIP); + + ctx.result = RESULT_FAILURE; +} + +static void test_pass(void) +{ + assert(ctx.result != RESULT_SKIP); + + if (ctx.result == RESULT_NONE) + ctx.result = RESULT_SUCCESS; +} + +static void test_todo(void) +{ + assert(ctx.result != RESULT_SKIP); + + if (ctx.result != RESULT_FAILURE) + ctx.result = RESULT_TODO; +} + +int test_assert(const char *location, const char *check, int ok) +{ + assert(ctx.running); + + if (ctx.result == RESULT_SKIP) { + test_msg("skipping check '%s' at %s", check, + make_relative(location)); + return 1; + } + if (!ctx.todo) { + if (ok) { + test_pass(); + } else { + test_msg("check \"%s\" failed at %s", check, + make_relative(location)); + test_fail(); + } + } + + return !!ok; +} + +void test__todo_begin(void) +{ + assert(ctx.running); + assert(!ctx.todo); + + ctx.todo = 1; +} + +int test__todo_end(const char *location, const char *check, int res) +{ + assert(ctx.running); + assert(ctx.todo); + + ctx.todo = 0; + if (ctx.result == RESULT_SKIP) + return 1; + if (res) { + test_msg("todo check '%s' succeeded at %s", check, + make_relative(location)); + test_fail(); + } else { + test_todo(); + } + + return !res; +} + +int check_bool_loc(const char *loc, const char *check, int ok) +{ + return test_assert(loc, check, ok); +} + +union test__tmp test__tmp[2]; + +int check_int_loc(const char *loc, const char *check, int ok, + intmax_t a, intmax_t b) +{ + int ret = test_assert(loc, check, ok); + + if (!ret) { + test_msg(" left: %"PRIdMAX, a); + test_msg(" right: %"PRIdMAX, b); + } + + return ret; +} + +int check_uint_loc(const char *loc, const char *check, int ok, + uintmax_t a, uintmax_t b) +{ + int ret = test_assert(loc, check, ok); + + if (!ret) { + test_msg(" left: %"PRIuMAX, a); + test_msg(" right: %"PRIuMAX, b); + } + + return ret; +} + +static void print_one_char(char ch, char quote) +{ + if ((unsigned char)ch < 0x20u || ch == 0x7f) { + /* TODO: improve handling of \a, \b, \f ... */ + printf("\\%03o", (unsigned char)ch); + } else { + if (ch == '\\' || ch == quote) + putc('\\', stdout); + putc(ch, stdout); + } +} + +static void print_char(const char *prefix, char ch) +{ + printf("# %s: '", prefix); + print_one_char(ch, '\''); + fputs("'\n", stdout); +} + +int check_char_loc(const char *loc, const char *check, int ok, char a, char b) +{ + int ret = test_assert(loc, check, ok); + + if (!ret) { + fflush(stderr); + print_char(" left", a); + print_char(" right", b); + fflush(stdout); + } + + return ret; +} + +static void print_str(const char *prefix, const char *str) +{ + printf("# %s: ", prefix); + if (!str) { + fputs("NULL\n", stdout); + } else { + putc('"', stdout); + while (*str) + print_one_char(*str++, '"'); + fputs("\"\n", stdout); + } +} + +int check_str_loc(const char *loc, const char *check, + const char *a, const char *b) +{ + int ok = (!a && !b) || (a && b && !strcmp(a, b)); + int ret = test_assert(loc, check, ok); + + if (!ret) { + fflush(stderr); + print_str(" left", a); + print_str(" right", b); + fflush(stdout); + } + + return ret; +} diff --git a/t/unit-tests/test-lib.h b/t/unit-tests/test-lib.h new file mode 100644 index 0000000000..a8f07ae0b7 --- /dev/null +++ b/t/unit-tests/test-lib.h @@ -0,0 +1,149 @@ +#ifndef TEST_LIB_H +#define TEST_LIB_H + +#include "git-compat-util.h" + +/* + * Run a test function, returns 1 if the test succeeds, 0 if it + * fails. If test_skip_all() has been called then the test will not be + * run. The description for each test should be unique. For example: + * + * TEST(test_something(arg1, arg2), "something %d %d", arg1, arg2) + */ +#define TEST(t, ...) \ + test__run_end(test__run_begin() ? 0 : (t, 1), \ + TEST_LOCATION(), __VA_ARGS__) + +/* + * Print a test plan, should be called before any tests. If the number + * of tests is not known in advance test_done() will automatically + * print a plan at the end of the test program. + */ +void test_plan(int count); + +/* + * test_done() must be called at the end of main(). It will print the + * plan if plan() was not called at the beginning of the test program + * and returns the exit code for the test program. + */ +int test_done(void); + +/* Skip the current test. */ +__attribute__((format (printf, 1, 2))) +void test_skip(const char *format, ...); + +/* Skip all remaining tests. */ +__attribute__((format (printf, 1, 2))) +void test_skip_all(const char *format, ...); + +/* Print a diagnostic message to stdout. */ +__attribute__((format (printf, 1, 2))) +void test_msg(const char *format, ...); + +/* + * Test checks are built around test_assert(). checks return 1 on + * success, 0 on failure. If any check fails then the test will fail. To + * create a custom check define a function that wraps test_assert() and + * a macro to wrap that function to provide a source location and + * stringified arguments. Custom checks that take pointer arguments + * should be careful to check that they are non-NULL before + * dereferencing them. For example: + * + * static int check_oid_loc(const char *loc, const char *check, + * struct object_id *a, struct object_id *b) + * { + * int res = test_assert(loc, check, a && b && oideq(a, b)); + * + * if (!res) { + * test_msg(" left: %s", a ? oid_to_hex(a) : "NULL"; + * test_msg(" right: %s", b ? oid_to_hex(a) : "NULL"; + * + * } + * return res; + * } + * + * #define check_oid(a, b) \ + * check_oid_loc(TEST_LOCATION(), "oideq("#a", "#b")", a, b) + */ +int test_assert(const char *location, const char *check, int ok); + +/* Helper macro to pass the location to checks */ +#define TEST_LOCATION() TEST__MAKE_LOCATION(__LINE__) + +/* Check a boolean condition. */ +#define check(x) \ + check_bool_loc(TEST_LOCATION(), #x, x) +int check_bool_loc(const char *loc, const char *check, int ok); + +/* + * Compare two integers. Prints a message with the two values if the + * comparison fails. NB this is not thread safe. + */ +#define check_int(a, op, b) \ + (test__tmp[0].i = (a), test__tmp[1].i = (b), \ + check_int_loc(TEST_LOCATION(), #a" "#op" "#b, \ + test__tmp[0].i op test__tmp[1].i, \ + test__tmp[0].i, test__tmp[1].i)) +int check_int_loc(const char *loc, const char *check, int ok, + intmax_t a, intmax_t b); + +/* + * Compare two unsigned integers. Prints a message with the two values + * if the comparison fails. NB this is not thread safe. + */ +#define check_uint(a, op, b) \ + (test__tmp[0].u = (a), test__tmp[1].u = (b), \ + check_uint_loc(TEST_LOCATION(), #a" "#op" "#b, \ + test__tmp[0].u op test__tmp[1].u, \ + test__tmp[0].u, test__tmp[1].u)) +int check_uint_loc(const char *loc, const char *check, int ok, + uintmax_t a, uintmax_t b); + +/* + * Compare two chars. Prints a message with the two values if the + * comparison fails. NB this is not thread safe. + */ +#define check_char(a, op, b) \ + (test__tmp[0].c = (a), test__tmp[1].c = (b), \ + check_char_loc(TEST_LOCATION(), #a" "#op" "#b, \ + test__tmp[0].c op test__tmp[1].c, \ + test__tmp[0].c, test__tmp[1].c)) +int check_char_loc(const char *loc, const char *check, int ok, + char a, char b); + +/* Check whether two strings are equal. */ +#define check_str(a, b) \ + check_str_loc(TEST_LOCATION(), "!strcmp("#a", "#b")", a, b) +int check_str_loc(const char *loc, const char *check, + const char *a, const char *b); + +/* + * Wrap a check that is known to fail. If the check succeeds then the + * test will fail. Returns 1 if the check fails, 0 if it + * succeeds. For example: + * + * TEST_TODO(check(0)); + */ +#define TEST_TODO(check) \ + (test__todo_begin(), test__todo_end(TEST_LOCATION(), #check, check)) + +/* Private helpers */ + +#define TEST__STR(x) #x +#define TEST__MAKE_LOCATION(line) __FILE__ ":" TEST__STR(line) + +union test__tmp { + intmax_t i; + uintmax_t u; + char c; +}; + +extern union test__tmp test__tmp[2]; + +int test__run_begin(void); +__attribute__((format (printf, 3, 4))) +int test__run_end(int, const char *, const char *, ...); +void test__todo_begin(void); +int test__todo_end(const char *, const char *, int); + +#endif /* TEST_LIB_H */ diff --git a/t/valgrind/valgrind.sh b/t/valgrind/valgrind.sh index 669ebaf68b..3c8ee19975 100755 --- a/t/valgrind/valgrind.sh +++ b/t/valgrind/valgrind.sh @@ -23,7 +23,7 @@ memcheck) VALGRIND_MAJOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*\([0-9]*\)') VALGRIND_MINOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*[0-9]*\.\([0-9]*\)') test 3 -gt "$VALGRIND_MAJOR" || - test 3 -eq "$VALGRIND_MAJOR" -a 4 -gt "$VALGRIND_MINOR" || + { test 3 -eq "$VALGRIND_MAJOR" && test 4 -gt "$VALGRIND_MINOR"; } || TOOL_OPTIONS="$TOOL_OPTIONS --track-origins=yes" ;; *) diff --git a/templates/hooks--pre-commit.sample b/templates/hooks--pre-commit.sample index e144712c85..29ed5ee486 100755 --- a/templates/hooks--pre-commit.sample +++ b/templates/hooks--pre-commit.sample @@ -28,7 +28,7 @@ if [ "$allownonascii" != "true" ] && # Note that the use of brackets around a tr range is ok here, (it's # even required, for portability to Solaris 10's /usr/bin/tr), since # the square bracket bytes happen to fall in the designated range. - test $(git diff --cached --name-only --diff-filter=A -z $against | + test $(git diff-index --cached --name-only --diff-filter=A -z $against | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 then cat <<\EOF diff --git a/tmp-objdir.c b/tmp-objdir.c index 5f9074ad1c..3509258be5 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -6,7 +6,6 @@ #include "environment.h" #include "object-file.h" #include "path.h" -#include "sigchain.h" #include "string-list.h" #include "strbuf.h" #include "strvec.h" @@ -18,7 +18,7 @@ * 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/>. + * along with this program; if not, see <https://www.gnu.org/licenses/>. */ #include "git-compat-util.h" @@ -1,12 +1,9 @@ #include "git-compat-util.h" #include "config.h" -#include "json-writer.h" -#include "quote.h" #include "repository.h" #include "run-command.h" #include "sigchain.h" #include "thread-utils.h" -#include "version.h" #include "trace.h" #include "trace2.h" #include "trace2/tr2_cfg.h" @@ -20,6 +17,7 @@ #include "trace2/tr2_tmr.h" static int trace2_enabled; +static int trace2_redact = 1; static int tr2_next_child_id; /* modify under lock */ static int tr2_next_exec_id; /* modify under lock */ @@ -227,6 +225,8 @@ void trace2_initialize_fl(const char *file, int line) if (!tr2_tgt_want_builtins()) return; trace2_enabled = 1; + if (!git_env_bool("GIT_TRACE2_REDACT", 1)) + trace2_redact = 0; tr2_sid_get(); @@ -247,12 +247,93 @@ int trace2_is_enabled(void) return trace2_enabled; } +/* + * Redacts an argument, i.e. ensures that no password in + * https://user:password@host/-style URLs is logged. + * + * Returns the original if nothing needed to be redacted. + * Returns a pointer that needs to be `free()`d otherwise. + */ +static const char *redact_arg(const char *arg) +{ + const char *p, *colon; + size_t at; + + if (!trace2_redact || + (!skip_prefix(arg, "https://", &p) && + !skip_prefix(arg, "http://", &p))) + return arg; + + at = strcspn(p, "@/"); + if (p[at] != '@') + return arg; + + colon = memchr(p, ':', at); + if (!colon) + return arg; + + return xstrfmt("%.*s:<REDACTED>%s", (int)(colon - arg), arg, p + at); +} + +/* + * Redacts arguments in an argument list. + * + * Returns the original if nothing needed to be redacted. + * Otherwise, returns a new array that needs to be released + * via `free_redacted_argv()`. + */ +static const char **redact_argv(const char **argv) +{ + int i, j; + const char *redacted = NULL; + const char **ret; + + if (!trace2_redact) + return argv; + + for (i = 0; argv[i]; i++) + if ((redacted = redact_arg(argv[i])) != argv[i]) + break; + + if (!argv[i]) + return argv; + + for (j = 0; argv[j]; j++) + ; /* keep counting */ + + ALLOC_ARRAY(ret, j + 1); + ret[j] = NULL; + + for (j = 0; j < i; j++) + ret[j] = argv[j]; + ret[i] = redacted; + for (++i; argv[i]; i++) { + redacted = redact_arg(argv[i]); + ret[i] = redacted ? redacted : argv[i]; + } + + return ret; +} + +static void free_redacted_argv(const char **redacted, const char **argv) +{ + int i; + + if (redacted != argv) { + for (i = 0; argv[i]; i++) + if (redacted[i] != argv[i]) + free((void *)redacted[i]); + free((void *)redacted); + } +} + void trace2_cmd_start_fl(const char *file, int line, const char **argv) { struct tr2_tgt *tgt_j; int j; uint64_t us_now; uint64_t us_elapsed_absolute; + const char **redacted; if (!trace2_enabled) return; @@ -260,10 +341,14 @@ void trace2_cmd_start_fl(const char *file, int line, const char **argv) us_now = getnanotime() / 1000; us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + redacted = redact_argv(argv); + for_each_wanted_builtin (j, tgt_j) if (tgt_j->pfn_start_fl) tgt_j->pfn_start_fl(file, line, us_elapsed_absolute, - argv); + redacted); + + free_redacted_argv(redacted, argv); } void trace2_cmd_exit_fl(const char *file, int line, int code) @@ -409,6 +494,7 @@ void trace2_child_start_fl(const char *file, int line, int j; uint64_t us_now; uint64_t us_elapsed_absolute; + const char **orig_argv = cmd->args.v; if (!trace2_enabled) return; @@ -419,10 +505,24 @@ void trace2_child_start_fl(const char *file, int line, cmd->trace2_child_id = tr2tls_locked_increment(&tr2_next_child_id); cmd->trace2_child_us_start = us_now; + /* + * The `pfn_child_start_fl` API takes a `struct child_process` + * rather than a simple `argv` for the child because some + * targets make use of the additional context bits/values. So + * temporarily replace the original argv (inside the `strvec`) + * with a possibly redacted version. + */ + cmd->args.v = redact_argv(orig_argv); + for_each_wanted_builtin (j, tgt_j) if (tgt_j->pfn_child_start_fl) tgt_j->pfn_child_start_fl(file, line, us_elapsed_absolute, cmd); + + if (cmd->args.v != orig_argv) { + free_redacted_argv(cmd->args.v, orig_argv); + cmd->args.v = orig_argv; + } } void trace2_child_exit_fl(const char *file, int line, struct child_process *cmd, @@ -493,6 +593,7 @@ int trace2_exec_fl(const char *file, int line, const char *exe, int exec_id; uint64_t us_now; uint64_t us_elapsed_absolute; + const char **redacted; if (!trace2_enabled) return -1; @@ -502,10 +603,14 @@ int trace2_exec_fl(const char *file, int line, const char *exe, exec_id = tr2tls_locked_increment(&tr2_next_exec_id); + redacted = redact_argv(argv); + for_each_wanted_builtin (j, tgt_j) if (tgt_j->pfn_exec_fl) tgt_j->pfn_exec_fl(file, line, us_elapsed_absolute, - exec_id, exe, argv); + exec_id, exe, redacted); + + free_redacted_argv(redacted, argv); return exec_id; } @@ -637,13 +742,19 @@ void trace2_def_param_fl(const char *file, int line, const char *param, { struct tr2_tgt *tgt_j; int j; + const char *redacted; if (!trace2_enabled) return; + redacted = redact_arg(value); + for_each_wanted_builtin (j, tgt_j) if (tgt_j->pfn_param_fl) - tgt_j->pfn_param_fl(file, line, param, value, kvi); + tgt_j->pfn_param_fl(file, line, param, redacted, kvi); + + if (redacted != value) + free((void *)redacted); } void trace2_def_repo_fl(const char *file, int line, struct repository *repo) @@ -337,8 +337,8 @@ struct key_value_info; void trace2_def_param_fl(const char *file, int line, const char *param, const char *value, const struct key_value_info *kvi); -#define trace2_def_param(param, value) \ - trace2_def_param_fl(__FILE__, __LINE__, (param), (value)) +#define trace2_def_param(param, value, kvi) \ + trace2_def_param_fl(__FILE__, __LINE__, (param), (value), (kvi)) /* * Tell trace2 about a newly instantiated repo object and assign diff --git a/trace2/tr2_ctr.c b/trace2/tr2_ctr.c index 87cf9034fb..d3a33715c1 100644 --- a/trace2/tr2_ctr.c +++ b/trace2/tr2_ctr.c @@ -1,5 +1,4 @@ #include "git-compat-util.h" -#include "thread-utils.h" #include "trace2/tr2_tgt.h" #include "trace2/tr2_tls.h" #include "trace2/tr2_ctr.h" diff --git a/trace2/tr2_sysenv.c b/trace2/tr2_sysenv.c index d3ecac2772..048cdd5438 100644 --- a/trace2/tr2_sysenv.c +++ b/trace2/tr2_sysenv.c @@ -68,6 +68,8 @@ static int tr2_sysenv_cb(const char *key, const char *value, for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) { if (!strcmp(key, tr2_sysenv_settings[k].git_config_name)) { + if (!value) + return config_error_nonbool(key); free(tr2_sysenv_settings[k].value); tr2_sysenv_settings[k].value = xstrdup(value); return 0; diff --git a/trace2/tr2_tgt_normal.c b/trace2/tr2_tgt_normal.c index 38d5ebddf6..baef48aa69 100644 --- a/trace2/tr2_tgt_normal.c +++ b/trace2/tr2_tgt_normal.c @@ -2,6 +2,7 @@ #include "config.h" #include "repository.h" #include "run-command.h" +#include "strbuf.h" #include "quote.h" #include "version.h" #include "trace2/tr2_dst.h" diff --git a/trace2/tr2_tls.c b/trace2/tr2_tls.c index 601c9e5036..4f75392952 100644 --- a/trace2/tr2_tls.c +++ b/trace2/tr2_tls.c @@ -1,4 +1,5 @@ #include "git-compat-util.h" +#include "strbuf.h" #include "thread-utils.h" #include "trace.h" #include "trace2/tr2_tls.h" diff --git a/trace2/tr2_tls.h b/trace2/tr2_tls.h index f9049805d4..3dfe6557fc 100644 --- a/trace2/tr2_tls.h +++ b/trace2/tr2_tls.h @@ -1,7 +1,6 @@ #ifndef TR2_TLS_H #define TR2_TLS_H -#include "strbuf.h" #include "trace2/tr2_ctr.h" #include "trace2/tr2_tmr.h" diff --git a/trace2/tr2_tmr.c b/trace2/tr2_tmr.c index 31d0e4d1bd..51f564b07a 100644 --- a/trace2/tr2_tmr.c +++ b/trace2/tr2_tmr.c @@ -1,5 +1,4 @@ #include "git-compat-util.h" -#include "thread-utils.h" #include "trace2/tr2_tgt.h" #include "trace2/tr2_tls.h" #include "trace2/tr2_tmr.h" @@ -507,6 +507,8 @@ static int git_trailer_default_config(const char *conf_key, const char *value, warning(_("unknown value '%s' for key '%s'"), value, conf_key); } else if (!strcmp(trailer_item, "separators")) { + if (!value) + return config_error_nonbool(conf_key); separators = xstrdup(value); } } @@ -551,16 +553,22 @@ static int git_trailer_config(const char *conf_key, const char *value, case TRAILER_KEY: if (conf->key) warning(_("more than one %s"), conf_key); + if (!value) + return config_error_nonbool(conf_key); conf->key = xstrdup(value); break; case TRAILER_COMMAND: if (conf->command) warning(_("more than one %s"), conf_key); + if (!value) + return config_error_nonbool(conf_key); conf->command = xstrdup(value); break; case TRAILER_CMD: if (conf->cmd) warning(_("more than one %s"), conf_key); + if (!value) + return config_error_nonbool(conf_key); conf->cmd = xstrdup(value); break; case TRAILER_WHERE: @@ -809,28 +817,55 @@ static ssize_t last_line(const char *buf, size_t len) } /* - * Return the position of the start of the patch or the length of str if there - * is no patch in the message. + * Find the end of the log message as an offset from the start of the input + * (where callers of this function are interested in looking for a trailers + * block in the same input). We have to consider two categories of content that + * can come at the end of the input which we want to ignore (because they don't + * belong in the log message): + * + * (1) the "patch part" which begins with a "---" divider and has patch + * information (like the output of git-format-patch), and + * + * (2) any trailing comment lines, blank lines like in the output of "git + * commit -v", or stuff below the "cut" (scissor) line. + * + * As a formula, the situation looks like this: + * + * INPUT = LOG MESSAGE + IGNORED + * + * where IGNORED can be either of the two categories described above. It may be + * that there is nothing to ignore. Now it may be the case that the LOG MESSAGE + * contains a trailer block, but that's not the concern of this function. */ -static size_t find_patch_start(const char *str) +static size_t find_end_of_log_message(const char *input, int no_divider) { + size_t end; const char *s; - for (s = str; *s; s = next_line(s)) { - const char *v; + /* Assume the naive end of the input is already what we want. */ + end = strlen(input); + + /* Optionally skip over any patch part ("---" line and below). */ + if (!no_divider) { + for (s = input; *s; s = next_line(s)) { + const char *v; - if (skip_prefix(s, "---", &v) && isspace(*v)) - return s - str; + if (skip_prefix(s, "---", &v) && isspace(*v)) { + end = s - input; + break; + } + } } - return s - str; + /* Skip over other ignorable bits. */ + return end - ignored_log_message_bytes(input, end); } /* * Return the position of the first trailer line or len if there are no * trailers. */ -static size_t find_trailer_start(const char *buf, size_t len) +static size_t find_trailer_block_start(const char *buf, size_t len) { const char *s; ssize_t end_of_title, l; @@ -925,12 +960,6 @@ continue_outer_loop: return len; } -/* Return the position of the end of the trailers. */ -static size_t find_trailer_end(const char *buf, size_t len) -{ - return len - ignore_non_trailer(buf, len); -} - static int ends_with_blank_line(const char *buf, size_t len) { ssize_t ll = last_line(buf, len); @@ -1052,7 +1081,6 @@ void process_trailers(const char *file, LIST_HEAD(head); struct strbuf sb = STRBUF_INIT; struct trailer_info info; - size_t trailer_end; FILE *outfile = stdout; ensure_configured(); @@ -1063,11 +1091,10 @@ void process_trailers(const char *file, outfile = create_in_place_tempfile(file); parse_trailers(&info, sb.buf, &head, opts); - trailer_end = info.trailer_end - sb.buf; /* Print the lines before the trailers */ if (!opts->only_trailers) - fwrite(sb.buf, 1, info.trailer_start - sb.buf, outfile); + fwrite(sb.buf, 1, info.trailer_block_start, outfile); if (!opts->only_trailers && !info.blank_line_before_trailer) fprintf(outfile, "\n"); @@ -1089,7 +1116,7 @@ void process_trailers(const char *file, /* Print the lines after the trailers as is */ if (!opts->only_trailers) - fwrite(sb.buf + trailer_end, 1, sb.len - trailer_end, outfile); + fwrite(sb.buf + info.trailer_block_end, 1, sb.len - info.trailer_block_end, outfile); if (opts->in_place) if (rename_tempfile(&trailers_tempfile, file)) @@ -1101,7 +1128,7 @@ void process_trailers(const char *file, void trailer_info_get(struct trailer_info *info, const char *str, const struct process_trailer_options *opts) { - int patch_start, trailer_end, trailer_start; + size_t end_of_log_message = 0, trailer_block_start = 0; struct strbuf **trailer_lines, **ptr; char **trailer_strings = NULL; size_t nr = 0, alloc = 0; @@ -1109,16 +1136,11 @@ void trailer_info_get(struct trailer_info *info, const char *str, ensure_configured(); - if (opts->no_divider) - patch_start = strlen(str); - else - patch_start = find_patch_start(str); - - trailer_end = find_trailer_end(str, patch_start); - trailer_start = find_trailer_start(str, trailer_end); + end_of_log_message = find_end_of_log_message(str, opts->no_divider); + trailer_block_start = find_trailer_block_start(str, end_of_log_message); - trailer_lines = strbuf_split_buf(str + trailer_start, - trailer_end - trailer_start, + trailer_lines = strbuf_split_buf(str + trailer_block_start, + end_of_log_message - trailer_block_start, '\n', 0); for (ptr = trailer_lines; *ptr; ptr++) { @@ -1139,9 +1161,9 @@ void trailer_info_get(struct trailer_info *info, const char *str, strbuf_list_free(trailer_lines); info->blank_line_before_trailer = ends_with_blank_line(str, - trailer_start); - info->trailer_start = str + trailer_start; - info->trailer_end = str + trailer_end; + trailer_block_start); + info->trailer_block_start = trailer_block_start; + info->trailer_block_end = end_of_log_message; info->trailers = trailer_strings; info->trailer_nr = nr; } @@ -1156,6 +1178,7 @@ void trailer_info_release(struct trailer_info *info) static void format_trailer_info(struct strbuf *out, const struct trailer_info *info, + const char *msg, const struct process_trailer_options *opts) { size_t origlen = out->len; @@ -1165,8 +1188,8 @@ static void format_trailer_info(struct strbuf *out, if (!opts->only_trailers && !opts->unfold && !opts->filter && !opts->separator && !opts->key_only && !opts->value_only && !opts->key_value_separator) { - strbuf_add(out, info->trailer_start, - info->trailer_end - info->trailer_start); + strbuf_add(out, msg + info->trailer_block_start, + info->trailer_block_end - info->trailer_block_start); return; } @@ -1220,7 +1243,7 @@ void format_trailers_from_commit(struct strbuf *out, const char *msg, struct trailer_info info; trailer_info_get(&info, msg, opts); - format_trailer_info(out, &info, opts); + format_trailer_info(out, &info, msg, opts); trailer_info_release(&info); } @@ -32,16 +32,16 @@ int trailer_set_if_missing(enum trailer_if_missing *item, const char *value); struct trailer_info { /* * True if there is a blank line before the location pointed to by - * trailer_start. + * trailer_block_start. */ int blank_line_before_trailer; /* - * Pointers to the start and end of the trailer block found. If there - * is no trailer block found, these 2 pointers point to the end of the - * input string. + * Offsets to the trailer block start and end positions in the input + * string. If no trailer block is found, these are both set to the + * "true" end of the input (find_end_of_log_message()). */ - const char *trailer_start, *trailer_end; + size_t trailer_block_start, trailer_block_end; /* * Array of trailers found. diff --git a/transport-helper.c b/transport-helper.c index 49811ef176..dd6002b393 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -3,13 +3,11 @@ #include "quote.h" #include "run-command.h" #include "commit.h" -#include "diff.h" #include "environment.h" #include "gettext.h" #include "hex.h" #include "object-name.h" #include "repository.h" -#include "revision.h" #include "remote.h" #include "string-list.h" #include "thread-utils.h" @@ -19,6 +17,7 @@ #include "refspec.h" #include "transport-internal.h" #include "protocol.h" +#include "packfile.h" static int debug; @@ -434,6 +433,8 @@ static int fetch_with_fetch(struct transport *transport, warning(_("%s unexpectedly said: '%s'"), data->name, buf.buf); } strbuf_release(&buf); + + reprepare_packed_git(the_repository); return 0; } @@ -628,7 +629,8 @@ static int process_connect_service(struct transport *transport, ret = run_connect(transport, &cmdbuf); } else if (data->stateless_connect && (get_protocol_version_config() == protocol_v2) && - !strcmp("git-upload-pack", name)) { + (!strcmp("git-upload-pack", name) || + !strcmp("git-upload-archive", name))) { strbuf_addf(&cmdbuf, "stateless-connect %s\n", name); ret = run_connect(transport, &cmdbuf); if (ret) @@ -645,6 +647,7 @@ static int process_connect(struct transport *transport, struct helper_data *data = transport->data; const char *name; const char *exec; + int ret; name = for_push ? "git-receive-pack" : "git-upload-pack"; if (for_push) @@ -652,7 +655,10 @@ static int process_connect(struct transport *transport, else exec = data->transport_options.uploadpack; - return process_connect_service(transport, name, exec); + ret = process_connect_service(transport, name, exec); + if (ret) + do_take_over(transport); + return ret; } static int connect_helper(struct transport *transport, const char *name, @@ -662,14 +668,14 @@ static int connect_helper(struct transport *transport, const char *name, /* Get_helper so connect is inited. */ get_helper(transport); - if (!data->connect) - die(_("operation not supported by protocol")); if (!process_connect_service(transport, name, exec)) die(_("can't connect to subservice %s"), name); fd[0] = data->helper->out; fd[1] = data->helper->in; + + do_take_over(transport); return 0; } @@ -684,10 +690,8 @@ static int fetch_refs(struct transport *transport, get_helper(transport); - if (process_connect(transport, 0)) { - do_take_over(transport); + if (process_connect(transport, 0)) return transport->vtable->fetch_refs(transport, nr_heads, to_fetch); - } /* * If we reach here, then the server, the client, and/or the transport @@ -1144,10 +1148,8 @@ static int push_refs(struct transport *transport, { struct helper_data *data = transport->data; - if (process_connect(transport, 1)) { - do_take_over(transport); + if (process_connect(transport, 1)) return transport->vtable->push_refs(transport, remote_refs, flags); - } if (!remote_refs) { fprintf(stderr, @@ -1188,11 +1190,9 @@ static struct ref *get_refs_list(struct transport *transport, int for_push, { get_helper(transport); - if (process_connect(transport, for_push)) { - do_take_over(transport); + if (process_connect(transport, for_push)) return transport->vtable->get_refs_list(transport, for_push, transport_options); - } return get_refs_list_using_list(transport, for_push); } @@ -1276,10 +1276,8 @@ static int get_bundle_uri(struct transport *transport) { get_helper(transport); - if (process_connect(transport, 0)) { - do_take_over(transport); + if (process_connect(transport, 0)) return transport->vtable->get_bundle_uri(transport); - } return -1; } diff --git a/transport.c b/transport.c index 219af8fd50..df518ead70 100644 --- a/transport.c +++ b/transport.c @@ -10,9 +10,7 @@ #include "remote.h" #include "connect.h" #include "send-pack.h" -#include "walker.h" #include "bundle.h" -#include "dir.h" #include "gettext.h" #include "refs.h" #include "refspec.h" @@ -26,7 +24,6 @@ #include "transport-internal.h" #include "protocol.h" #include "object-name.h" -#include "object-store-ll.h" #include "color.h" #include "bundle-uri.h" @@ -1470,6 +1467,7 @@ int transport_push(struct repository *r, if (porcelain && !push_ret) puts("Done"); else if (!quiet && !ret && !transport_refs_pushed(remote_refs)) + /* stable plumbing output; do not modify or localize */ fprintf(stderr, "Everything up-to-date\n"); done: @@ -1,12 +1,9 @@ #include "git-compat-util.h" -#include "cache-tree.h" #include "hex.h" #include "tree.h" #include "object-name.h" #include "object-store-ll.h" -#include "blob.h" #include "commit.h" -#include "tag.h" #include "alloc.h" #include "tree-walk.h" #include "repository.h" diff --git a/upload-pack.c b/upload-pack.c index ea234ab6a4..6e0d441ef5 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -9,13 +9,10 @@ #include "repository.h" #include "object-store-ll.h" #include "oid-array.h" -#include "tag.h" #include "object.h" #include "commit.h" #include "diff.h" #include "revision.h" -#include "list-objects.h" -#include "list-objects-filter.h" #include "list-objects-filter-options.h" #include "run-command.h" #include "connect.h" @@ -24,11 +21,8 @@ #include "string-list.h" #include "strvec.h" #include "trace2.h" -#include "prio-queue.h" #include "protocol.h" -#include "quote.h" #include "upload-pack.h" -#include "serve.h" #include "commit-graph.h" #include "commit-reach.h" #include "shallow.h" @@ -469,7 +463,7 @@ static void create_pack_file(struct upload_pack_data *pack_data, fail: free(output_state); - send_client_data(3, abort_msg, sizeof(abort_msg), + send_client_data(3, abort_msg, strlen(abort_msg), pack_data->use_sideband); die("git upload-pack: %s", abort_msg); } diff --git a/userdiff.c b/userdiff.c index e399543823..92ef649c99 100644 --- a/userdiff.c +++ b/userdiff.c @@ -3,6 +3,7 @@ #include "userdiff.h" #include "attr.h" #include "strbuf.h" +#include "environment.h" static struct userdiff_driver *drivers; static int ndrivers; @@ -323,8 +324,7 @@ static int userdiff_find_by_namelen_cb(struct userdiff_driver *driver, { struct find_by_namelen_data *cb_data = priv; - if (!strncmp(driver->name, cb_data->name, cb_data->len) && - !driver->name[cb_data->len]) { + if (!xstrncmpz(driver->name, cb_data->name, cb_data->len)) { cb_data->driver = driver; return 1; /* tell the caller to stop iterating */ } @@ -460,7 +460,8 @@ struct userdiff_driver *userdiff_get_textconv(struct repository *r, if (!driver->textconv) return NULL; - if (driver->textconv_want_cache && !driver->textconv_cache) { + if (driver->textconv_want_cache && !driver->textconv_cache && + have_git_dir()) { struct notes_cache *c = xmalloc(sizeof(*c)); struct strbuf name = STRBUF_INIT; @@ -2,7 +2,7 @@ #include "strbuf.h" #include "utf8.h" -/* This code is originally from http://www.cl.cam.ac.uk/~mgk25/ucs/ */ +/* This code is originally from https://www.cl.cam.ac.uk/~mgk25/ucs/ */ static const char utf16_be_bom[] = {'\xFE', '\xFF'}; static const char utf16_le_bom[] = {'\xFF', '\xFE'}; @@ -83,7 +83,7 @@ void strbuf_utf8_align(struct strbuf *buf, align_type position, unsigned int wid * BOM must not be used [1]. The same applies for the UTF-32 equivalents. * The function returns true if this rule is violated. * - * [1] http://unicode.org/faq/utf_bom.html#bom10 + * [1] https://unicode.org/faq/utf_bom.html#bom10 */ int has_prohibited_utf_bom(const char *enc, const char *data, size_t len); @@ -99,8 +99,8 @@ int has_prohibited_utf_bom(const char *enc, const char *data, size_t len); * Therefore, strictly requiring a BOM seems to be the safest option for * content in Git. * - * [1] http://unicode.org/faq/utf_bom.html#gen6 - * [2] http://www.unicode.org/versions/Unicode10.0.0/ch03.pdf + * [1] https://unicode.org/faq/utf_bom.html#gen6 + * [2] https://www.unicode.org/versions/Unicode10.0.0/ch03.pdf * Section 3.10, D98, page 132 * [3] https://encoding.spec.whatwg.org/#utf-16le */ diff --git a/worktree.c b/worktree.c index a56a6c2a3d..b02a05a74a 100644 --- a/worktree.c +++ b/worktree.c @@ -12,18 +12,23 @@ #include "wt-status.h" #include "config.h" +void free_worktree(struct worktree *worktree) +{ + if (!worktree) + return; + free(worktree->path); + free(worktree->id); + free(worktree->head_ref); + free(worktree->lock_reason); + free(worktree->prune_reason); + free(worktree); +} + void free_worktrees(struct worktree **worktrees) { int i = 0; - - for (i = 0; worktrees[i]; i++) { - free(worktrees[i]->path); - free(worktrees[i]->id); - free(worktrees[i]->head_ref); - free(worktrees[i]->lock_reason); - free(worktrees[i]->prune_reason); - free(worktrees[i]); - } + for (i = 0; worktrees[i]; i++) + free_worktree(worktrees[i]); free (worktrees); } @@ -51,7 +56,7 @@ static void add_head_info(struct worktree *wt) /** * get the main worktree */ -static struct worktree *get_main_worktree(void) +static struct worktree *get_main_worktree(int skip_reading_head) { struct worktree *worktree = NULL; struct strbuf worktree_path = STRBUF_INIT; @@ -70,11 +75,13 @@ static struct worktree *get_main_worktree(void) */ worktree->is_bare = (is_bare_repository_cfg == 1) || is_bare_repository(); - add_head_info(worktree); + if (!skip_reading_head) + add_head_info(worktree); return worktree; } -static struct worktree *get_linked_worktree(const char *id) +struct worktree *get_linked_worktree(const char *id, + int skip_reading_head) { struct worktree *worktree = NULL; struct strbuf path = STRBUF_INIT; @@ -93,7 +100,8 @@ static struct worktree *get_linked_worktree(const char *id) CALLOC_ARRAY(worktree, 1); worktree->path = strbuf_detach(&worktree_path, NULL); worktree->id = xstrdup(id); - add_head_info(worktree); + if (!skip_reading_head) + add_head_info(worktree); done: strbuf_release(&path); @@ -118,7 +126,14 @@ static void mark_current_worktree(struct worktree **worktrees) free(git_dir); } -struct worktree **get_worktrees(void) +/* + * NEEDSWORK: This function exists so that we can look up metadata of a + * worktree without trying to access any of its internals like the refdb. It + * would be preferable to instead have a corruption-tolerant function for + * retrieving worktree metadata that could be used when the worktree is known + * to not be in a healthy state, e.g. when creating or repairing it. + */ +static struct worktree **get_worktrees_internal(int skip_reading_head) { struct worktree **list = NULL; struct strbuf path = STRBUF_INIT; @@ -128,7 +143,7 @@ struct worktree **get_worktrees(void) ALLOC_ARRAY(list, alloc); - list[counter++] = get_main_worktree(); + list[counter++] = get_main_worktree(skip_reading_head); strbuf_addf(&path, "%s/worktrees", get_git_common_dir()); dir = opendir(path.buf); @@ -137,7 +152,7 @@ struct worktree **get_worktrees(void) while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) { struct worktree *linked = NULL; - if ((linked = get_linked_worktree(d->d_name))) { + if ((linked = get_linked_worktree(d->d_name, skip_reading_head))) { ALLOC_GROW(list, counter + 1, alloc); list[counter++] = linked; } @@ -151,6 +166,11 @@ struct worktree **get_worktrees(void) return list; } +struct worktree **get_worktrees(void) +{ + return get_worktrees_internal(0); +} + const char *get_worktree_git_dir(const struct worktree *wt) { if (!wt) @@ -395,9 +415,9 @@ int is_worktree_being_bisected(const struct worktree *wt, memset(&state, 0, sizeof(state)); found_bisect = wt_status_check_bisect(wt, &state) && - state.branch && + state.bisecting_from && skip_prefix(target, "refs/heads/", &target) && - !strcmp(state.branch, target); + !strcmp(state.bisecting_from, target); wt_status_state_free_buffers(&state); return found_bisect; } @@ -591,7 +611,7 @@ static void repair_noop(int iserr UNUSED, void repair_worktrees(worktree_repair_fn fn, void *cb_data) { - struct worktree **worktrees = get_worktrees(); + struct worktree **worktrees = get_worktrees_internal(1); struct worktree **wt = worktrees + 1; /* +1 skips main worktree */ if (!fn) diff --git a/worktree.h b/worktree.h index ce45b66de9..f14784a2ff 100644 --- a/worktree.h +++ b/worktree.h @@ -58,6 +58,13 @@ struct worktree *find_worktree(struct worktree **list, const char *arg); /* + * Look up the worktree corresponding to `id`, or NULL of no such worktree + * exists. + */ +struct worktree *get_linked_worktree(const char *id, + int skip_reading_head); + +/* * Return the worktree corresponding to `path`, or NULL if no such worktree * exists. */ @@ -135,6 +142,11 @@ void repair_worktrees(worktree_repair_fn, void *cb_data); void repair_worktree_at_path(const char *, worktree_repair_fn, void *cb_data); /* + * Free up the memory for a worktree. + */ +void free_worktree(struct worktree *); + +/* * Free up the memory for worktree(s) */ void free_worktrees(struct worktree **); @@ -5,7 +5,6 @@ #include "abspath.h" #include "parse.h" #include "gettext.h" -#include "repository.h" #include "strbuf.h" #include "trace2.h" diff --git a/write-or-die.c b/write-or-die.c index 42a2dc73cd..01a9a51fa2 100644 --- a/write-or-die.c +++ b/write-or-die.c @@ -18,23 +18,20 @@ */ void maybe_flush_or_die(FILE *f, const char *desc) { - static int skip_stdout_flush = -1; - struct stat st; - char *cp; - if (f == stdout) { - if (skip_stdout_flush < 0) { - /* NEEDSWORK: make this a normal Boolean */ - cp = getenv("GIT_FLUSH"); - if (cp) - skip_stdout_flush = (atoi(cp) == 0); - else if ((fstat(fileno(stdout), &st) == 0) && - S_ISREG(st.st_mode)) - skip_stdout_flush = 1; - else - skip_stdout_flush = 0; + static int force_flush_stdout = -1; + + if (force_flush_stdout < 0) { + force_flush_stdout = git_env_bool("GIT_FLUSH", -1); + if (force_flush_stdout < 0) { + struct stat st; + if (fstat(fileno(stdout), &st)) + force_flush_stdout = 1; + else + force_flush_stdout = !S_ISREG(st.st_mode); + } } - if (skip_stdout_flush && !ferror(f)) + if (!force_flush_stdout && !ferror(f)) return; } if (fflush(f)) { diff --git a/wt-status.c b/wt-status.c index 9f45bf6949..b5a29083df 100644 --- a/wt-status.c +++ b/wt-status.c @@ -861,6 +861,7 @@ void wt_status_state_free_buffers(struct wt_status_state *state) FREE_AND_NULL(state->branch); FREE_AND_NULL(state->onto); FREE_AND_NULL(state->detached_from); + FREE_AND_NULL(state->bisecting_from); } static void wt_longstatus_print_unmerged(struct wt_status *s) @@ -1295,26 +1296,32 @@ static char *read_line_from_git_path(const char *filename) static int split_commit_in_progress(struct wt_status *s) { int split_in_progress = 0; - char *head, *orig_head, *rebase_amend, *rebase_orig_head; + struct object_id head_oid, orig_head_oid; + char *rebase_amend, *rebase_orig_head; + int head_flags, orig_head_flags; if ((!s->amend && !s->nowarn && !s->workdir_dirty) || !s->branch || strcmp(s->branch, "HEAD")) return 0; - head = read_line_from_git_path("HEAD"); - orig_head = read_line_from_git_path("ORIG_HEAD"); + if (read_ref_full("HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, + &head_oid, &head_flags) || + read_ref_full("ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE, + &orig_head_oid, &orig_head_flags)) + return 0; + if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF) + return 0; + rebase_amend = read_line_from_git_path("rebase-merge/amend"); rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head"); - if (!head || !orig_head || !rebase_amend || !rebase_orig_head) + if (!rebase_amend || !rebase_orig_head) ; /* fall through, no split in progress */ else if (!strcmp(rebase_amend, rebase_orig_head)) - split_in_progress = !!strcmp(head, rebase_amend); - else if (strcmp(orig_head, rebase_orig_head)) + split_in_progress = !!strcmp(oid_to_hex(&head_oid), rebase_amend); + else if (strcmp(oid_to_hex(&orig_head_oid), rebase_orig_head)) split_in_progress = 1; - free(head); - free(orig_head); free(rebase_amend); free(rebase_orig_head); @@ -1569,10 +1576,10 @@ static void show_revert_in_progress(struct wt_status *s, static void show_bisect_in_progress(struct wt_status *s, const char *color) { - if (s->state.branch) + if (s->state.bisecting_from) status_printf_ln(s, color, _("You are currently bisecting, started from branch '%s'."), - s->state.branch); + s->state.bisecting_from); else status_printf_ln(s, color, _("You are currently bisecting.")); @@ -1733,7 +1740,7 @@ int wt_status_check_bisect(const struct worktree *wt, if (!stat(worktree_git_path(wt, "BISECT_LOG"), &st)) { state->bisect_in_progress = 1; - state->branch = get_branch(wt, "BISECT_START"); + state->bisecting_from = get_branch(wt, "BISECT_START"); return 1; } return 0; diff --git a/wt-status.h b/wt-status.h index ab9cc9d8f0..819dcad723 100644 --- a/wt-status.h +++ b/wt-status.h @@ -94,6 +94,7 @@ struct wt_status_state { char *branch; char *onto; char *detached_from; + char *bisecting_from; struct object_id detached_oid; struct object_id revert_head_oid; struct object_id cherry_pick_head_oid; diff --git a/xdiff-interface.c b/xdiff-interface.c index adcea109fa..3162f51743 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -1,4 +1,5 @@ #include "git-compat-util.h" +#include "gettext.h" #include "config.h" #include "hex.h" #include "object-store-ll.h" @@ -6,8 +7,6 @@ #include "xdiff-interface.h" #include "xdiff/xtypes.h" #include "xdiff/xdiffi.h" -#include "xdiff/xemit.h" -#include "xdiff/xmacros.h" #include "xdiff/xutils.h" struct xdiff_emit_state { @@ -313,7 +312,7 @@ int git_xmerge_config(const char *var, const char *value, { if (!strcmp(var, "merge.conflictstyle")) { if (!value) - die("'%s' is not a boolean", var); + return config_error_nonbool(var); if (!strcmp(value, "diff3")) git_xmerge_style = XDL_MERGE_DIFF3; else if (!strcmp(value, "zdiff3")) @@ -325,8 +324,8 @@ int git_xmerge_config(const char *var, const char *value, * git-completion.bash when you add new merge config */ else - die("unknown style '%s' given for '%s'", - value, var); + return error(_("unknown style '%s' given for '%s'"), + value, var); return 0; } return git_default_config(var, value, ctx, cb); |
